P0-1 fix: ledger/u grade badges are token-derived — kill blue-B / amber-C / non-A glow

Phone audit found LEDGER READ CARDS rendering B badges with BLUE borders + C
with AMBER right now in prod — GradePill (components/GradeCard.tsx) hardcoded the
OLD palette (rgba(74,158,255) blue-B, rgba(255,179,71) amber-C) for bg/border
while the text used the migrated token. Migrated bg/border to color-mix on the
grade token, so B renders neutral-white and C grey (matching the board).
- globals.css .grade-*-bg → token-derived color-mix (was raw blue/amber rgba).
- DELETED glow from .grade-glow-b/c/d (glow is A-tier ONLY, by law) — B/C/D keep
  their token color, no text-shadow.
- Purged the last dead grade-blue #4A9EFF fallbacks (SoccerGradeResult, the
  intelligence INFO dot).
- REGRESSION LOCK: vyndrParityQA fails if #4a9eff / rgba(74,158,255) reappears
  anywhere in web/src, if GradePill hardcodes blue/amber rgba, or if grade-glow
  B/C/D grow a text-shadow again.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-07-17 00:48:56 -04:00
parent 4f32eab859
commit 489d849f1e
5 changed files with 64 additions and 15 deletions
+9 -4
View File
@@ -76,10 +76,15 @@ const SPORTSBOOKS = [
function gradeTierClass(grade: string): { color: string; bg: string; border: string } {
const g = (grade || '').trim().toUpperCase().charAt(0);
if (g === 'A') return { color: 'var(--grade-a)', bg: 'rgba(0,200,150,0.10)', border: 'rgba(0,200,150,0.40)' };
if (g === 'B') return { color: 'var(--grade-b)', bg: 'rgba(74,158,255,0.10)', border: 'rgba(74,158,255,0.40)' };
if (g === 'C') return { color: 'var(--grade-c)', bg: 'rgba(255,179,71,0.10)', border: 'rgba(255,179,71,0.40)' };
return { color: 'var(--grade-d)', bg: 'rgba(255,107,107,0.10)', border: 'rgba(255,107,107,0.40)' };
// P0-1 — TOKEN-DERIVED (was hardcoded old palette: blue-B / amber-C).
// bg/border follow the grade token via color-mix,
// so B renders neutral-white and C grey, matching the board-row badges.
const tok = g === 'A' ? 'var(--grade-a)' : g === 'B' ? 'var(--grade-b)' : g === 'C' ? 'var(--grade-c)' : 'var(--grade-d)';
return {
color: tok,
bg: `color-mix(in srgb, ${tok} 12%, transparent)`,
border: `color-mix(in srgb, ${tok} 42%, transparent)`,
};
}
function confidenceLabel(sample?: number): { label: string; tone: 'high' | 'moderate' | 'limited' } {
+3 -3
View File
@@ -56,7 +56,7 @@ interface ParsedSignal {
const SIGNAL_TONE_STYLE: Record<SignalTone, { color: string; bg: string; border: string }> = {
positive: { color: 'var(--grade-a)', bg: 'rgba(0,200,150,0.08)', border: 'rgba(0,200,150,0.40)' },
caution: { color: 'var(--grade-c, #FFB347)', bg: 'rgba(255,179,71,0.08)', border: 'rgba(255,179,71,0.40)' },
caution: { color: 'var(--grade-c, #B8BCC8)', bg: 'rgba(255,179,71,0.08)', border: 'rgba(255,179,71,0.40)' },
warning: { color: 'var(--grade-d, #ff5a5a)', bg: 'rgba(255,90,90,0.08)', border: 'rgba(255,90,90,0.40)' },
neutral: { color: 'var(--text-secondary)', bg: 'transparent', border: 'var(--border)' },
};
@@ -163,8 +163,8 @@ function parseSignals(summary: string | undefined): ParsedSignal[] {
function gradeColor(grade: string): string {
const g = (grade || '').trim().toUpperCase().charAt(0);
if (g === 'A') return 'var(--grade-a)';
if (g === 'B') return 'var(--grade-b, #4A9EFF)';
if (g === 'C') return 'var(--grade-c, #FFB347)';
if (g === 'B') return 'var(--grade-b, #F0F0F0)';
if (g === 'C') return 'var(--grade-c, #B8BCC8)';
return 'var(--grade-d, #ff5a5a)';
}