P2-10: ledger read-card density — tighter padding/margins (3-4 per phone screen)
Phone audit: read cards were huge, only 1-2 fit per screen. Compressed the
vertical spacing — article padding 16->12, header margin 8->5, name 15->14px,
ladder-rungs margin 10->8, book/date line 12->8.
Kept the archetype showDesc: it renders INLINE (same row as the badge), so it
adds zero vertical height — dropping it wouldn't help density and would break
the ds5 design lock ("the badge shows its one-line meaning where it leads").
Locked the density in vyndrParityQA (P2-10).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -298,3 +298,14 @@ describe('P1-8 — Compare verdict is time-honest (form, not a phantom game)', (
|
|||||||
expect(compare).toMatch(/on current form/i);
|
expect(compare).toMatch(/on current form/i);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── P2-10 lock — ledger read cards are dense (3-4 per phone screen) ──────────
|
||||||
|
describe('P2-10 — ledger cards are tightened for density', () => {
|
||||||
|
const ledger = read('app/ledger/page.tsx');
|
||||||
|
it('the read card uses tight padding for density (3-4 per phone screen)', () => {
|
||||||
|
// the LedgerCard <article> padding dropped 16 -> 12 (showDesc is INLINE, so
|
||||||
|
// density comes from padding/margins, not from stripping the archetype meaning)
|
||||||
|
expect(ledger).toMatch(/animate-fade-up stagger-[^]*?padding: 12 \}\}>/);
|
||||||
|
expect(ledger).toMatch(/ArchetypeBadge[^]*?showDesc/); // meaning preserved (inline, no height cost)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -333,8 +333,8 @@ function LedgerCard({ row, index, ladder }: { row: LedgerRow; index: number; lad
|
|||||||
const rungs = Array.isArray(ladder) ? ladder : [row];
|
const rungs = Array.isArray(ladder) ? ladder : [row];
|
||||||
const isLadder = rungs.length > 1;
|
const isLadder = rungs.length > 1;
|
||||||
return (
|
return (
|
||||||
<article className={`surface diagonal-cut animate-fade-up stagger-${(index % 6) + 1}`} style={{ padding: 16 }}>
|
<article className={`surface diagonal-cut animate-fade-up stagger-${(index % 6) + 1}`} style={{ padding: 12 }}>
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 8 }}>
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 5 }}>
|
||||||
<span className="mono" style={{ fontSize: 10, fontWeight: 700, padding: '2px 8px', borderRadius: 999, background: `${sportColor}1F`, color: sportColor }}>
|
<span className="mono" style={{ fontSize: 10, fontWeight: 700, padding: '2px 8px', borderRadius: 999, background: `${sportColor}1F`, color: sportColor }}>
|
||||||
{row.sport.toUpperCase()}
|
{row.sport.toUpperCase()}
|
||||||
</span>
|
</span>
|
||||||
@@ -348,10 +348,13 @@ function LedgerCard({ row, index, ladder }: { row: LedgerRow; index: number; lad
|
|||||||
<GradePill grade={row.grade} />
|
<GradePill grade={row.grade} />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<h3 style={{ fontSize: 15, fontWeight: 600, marginBottom: 2 }}>{row.player_name}</h3>
|
<h3 style={{ fontSize: 14, fontWeight: 600, marginBottom: 2 }}>{row.player_name}</h3>
|
||||||
{/* Part 5 — the archetype glyph+chip, propagated (self-hides when absent). */}
|
{/* Part 5 — the archetype glyph+chip, propagated (self-hides when absent).
|
||||||
|
showDesc renders INLINE (same row), so it costs no vertical height —
|
||||||
|
kept for its one-line meaning. P2-10 density comes from the tighter
|
||||||
|
padding/margins, not from stripping this. */}
|
||||||
{row.archetype && (
|
{row.archetype && (
|
||||||
<div style={{ marginBottom: 6 }}>
|
<div style={{ marginBottom: 4 }}>
|
||||||
<ArchetypeBadge archetype={row.archetype} size="sm" showDesc />
|
<ArchetypeBadge archetype={row.archetype} size="sm" showDesc />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -362,7 +365,7 @@ function LedgerCard({ row, index, ladder }: { row: LedgerRow; index: number; lad
|
|||||||
<p className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'capitalize', marginBottom: 6 }}>
|
<p className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'capitalize', marginBottom: 6 }}>
|
||||||
{row.stat.replace(/_/g, ' ')} <span style={{ color: 'var(--text-tertiary)' }}>· {rungs.length} lines</span>
|
{row.stat.replace(/_/g, ' ')} <span style={{ color: 'var(--text-tertiary)' }}>· {rungs.length} lines</span>
|
||||||
</p>
|
</p>
|
||||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 10 }}>
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 8 }}>
|
||||||
{rungs.map((rung) => (
|
{rungs.map((rung) => (
|
||||||
<span key={rung.id} className="mono" style={{ fontSize: 10.5, display: 'inline-flex', alignItems: 'center', gap: 5, padding: '3px 8px', borderRadius: 6, background: 'var(--bg-2)', border: '1px solid var(--border)' }}>
|
<span key={rung.id} className="mono" style={{ fontSize: 10.5, display: 'inline-flex', alignItems: 'center', gap: 5, padding: '3px 8px', borderRadius: 6, background: 'var(--bg-2)', border: '1px solid var(--border)' }}>
|
||||||
{rung.side}{rung.line}
|
{rung.side}{rung.line}
|
||||||
@@ -376,7 +379,7 @@ function LedgerCard({ row, index, ladder }: { row: LedgerRow; index: number; lad
|
|||||||
{row.side} {row.line} {row.stat.replace(/_/g, ' ')}
|
{row.side} {row.line} {row.stat.replace(/_/g, ' ')}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<p className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', marginBottom: 12 }}>
|
<p className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', marginBottom: 8 }}>
|
||||||
{row.book ? <BookWordmark book={row.book} size={11} /> : '—'}{row.locked_odds ? ` · ${row.locked_odds}` : ''} · {row.game_date}
|
{row.book ? <BookWordmark book={row.book} size={11} /> : '—'}{row.locked_odds ? ` · ${row.locked_odds}` : ''} · {row.game_date}
|
||||||
{/* model_value is MODEL output — always labeled, never blended with market numbers. */}
|
{/* model_value is MODEL output — always labeled, never blended with market numbers. */}
|
||||||
{row.model_value != null && <span> · MODEL {row.model_value}</span>}
|
{row.model_value != null && <span> · MODEL {row.model_value}</span>}
|
||||||
|
|||||||
Reference in New Issue
Block a user