d3637e7abd
- specs/ROW-GRAMMAR.md: the row grammar law (slot order, color law, mark
law, mobile stacking, no-truncation), locked by tests/unit/rowGrammar.
StatStrip violations fixed: MovementChip before the grade (market
context before model output); ViabilityChips after the archetype
(identity is one contiguous run).
- Line-movement sparklines: intradayRefreshService.trackHistory captures
real {t,line} points per grade (seeded with the lock, deduped when
flat, capped 24) inside the snapshot write-back; StatStrip.LineSparkline
renders at >=3 points (green toward / amber against / dim flat).
- Last-10 dot strips: services/last10Dots (streaksService accessors) ->
/api/snapshot/:sport attaches last10_dots from rosterlogs:{sport};
StatStrip.DotStrip renders vs the LOCKED line, newest first.
- CLV distribution: getModelAggregate emits clv_distribution (7 signed
buckets, outliers clamped) only past the centralized n>=20 gate;
ledger MODEL header renders the bar strip.
- Global search: SearchModal (cmd-K via GlobalHosts + window.__search),
players via /api/players/search per sport + static lib/teams.js
(soccer deliberately absent); Nav search icon + Search first in the
mobile More sheet. Explore tab untouched.
- Landing LCP: fade-up floored at opacity .6 (hero h1 contentful on
first frame, S33 visible-floor rule) + IBM Plex Mono preload:false
(4 decorative font files off the slow-4G critical path).
2654 -> 2698 tests (226 suites) green; web build exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5.7 KiB
5.7 KiB
VYNDR — ROW-GRAMMAR.md v1.0
The row grammar law. Density is unlimited when grammar is fixed: every element is DATA with ONE meaning in the SAME slot on every row of its type. Locked by tests/unit/rowGrammar.test.js — a slot-order change that isn't a deliberate spec amendment fails the suite.
1. THE LAW
- One meaning per element. A mark (dot, chip, strikethrough, color) means exactly one thing, everywhere it appears.
- One slot per element. The same element renders in the same position on every row of its type. A reader who learns one row has learned every row.
- All data is mono (
var(--mono)/.mono) withtabular-numswhere numbers align. Data never glitches. - No truncation, ever, of a player name, a game time, or a pitcher line. Rows wrap or stack; they do not ellipsize identity or schedule facts. (
text-overflow: ellipsisis banned on those elements.) - Absent beats wrong. A slot with no real data renders nothing — never a placeholder value, never a fabricated zero.
2. CANONICAL PROP-ROW SLOT ORDER
Every prop row (StatStrip snapshot mode, and any future surface that renders a graded prop inline) reads left → right in this fixed order:
[1 identity] [2 viability] [3 stat+line+side] [4 market context] [5 model output] [6 outcome] [7 actions] [8 provenance]
| slot | contents | notes |
|---|---|---|
| 1 identity | player name · team · archetype badge | strip header — name appears ONCE per strip (S42 law) |
| 2 viability | lineup chip (CONFIRMED / NOT IN LINEUP / PROJ) · injury chip | real feeds only; absent feeds → no chips |
| 3 stat+line+side | TB O1.5 |
white, mono — the subject of the row |
| 4 market context | best-price dot · movement chip (STEAM ▲ / VALUE ▲) | what the MARKET is doing, before what the model says |
| 5 model output | revision strikethrough (original grade) → current grade badge | history then present: A̶ B reads "was A, now B" |
| 6 outcome | settled chip (✓ HIT / ✕ MISS / PUSH + actual) | once settled, actions (slot 7) disappear — the bet is over |
| 7 actions | parlay + · BOOK IT ⟶ |
suppressed when dead or settled |
| 8 provenance | Graded 2h ago at -115 |
the receipt, always last |
Sub-line (stat + market context, one line under the row, in this order):
[last-10 dot strip] [line-movement sparkline] [current-line delta]
- Each sub-line element renders only when its real data exists (dots need a real game log; the sparkline needs ≥3 captured history points; the delta needs a previous snapshot). Zero real data → no sub-line.
Strip header order (slot 1 + 2): name → team → archetype → viability chips. Identity is one contiguous run; status chips follow it.
3. COLOR LAW — one meaning per color
| color | meaning | examples |
|---|---|---|
signal green --g-a / --hit |
edge / best / confirmed-positive | grade-A badge, best-price dot, VALUE chip, HIT chip, CONFIRMED lineup, delta TOWARD, CLV beat, dot-strip filled ● (cleared the line) |
amber --amber |
caution / steam / building | STEAM chip, GTD injury, delta AWAY, RECORD BUILDING, SYNC at 1.5× |
red --miss |
settled-negative truth ONLY: miss / dead / stale / faded close | MISS chip, NOT IN LINEUP, OUT, SYNC STALE, CLV faded |
dim --text-1/2 |
absent / projected / neutral | PROJ lineup, awaiting copy, PUSH, dot-strip hollow ○ (didn't clear) |
Red is never used for mere movement-against or a lower price — those are amber (caution) and plain (fact). The line-movement sparkline is therefore green when the net move is TOWARD the graded side, amber when net AGAINST, dim when flat — never red (nothing has settled).
4. MARK LAW — the micro-vocabulary
- ● / ○ dot strip — last 10 games vs TONIGHT'S locked line, newest first. Filled green = that game's stat cleared the line; hollow dim = it didn't. Real game logs only; no log → no dots.
- sparkline — the REAL captured line over time (intraday refresh history, {t, line} points, capped 24). Never rendered under 3 real points.
- strikethrough — a dead or superseded model read (NOT IN LINEUP grade, revised-from grade). The original is preserved, struck, never deleted.
- ▲ ▼ — line movement direction (market fact). ✓ ✕ — settled result.
- glow — A-tier only (NORTH STAR rule). Chrome may glitch; data never.
5. MOBILE STACKING (≤390px physics)
- A prop row WRAPS (
flexWrap) — slots keep their order, overflowing slots continue on the next visual line. Order is never re-shuffled for width. - The sub-line always stacks BELOW its row, full width.
- Strip header wraps after the identity run; viability chips may drop to a second line but stay ahead of the stats run.
- Wide data grids (
game-lines-grid) scroll horizontally inside their own container; the page never scrolls horizontally. - Names, game times, and pitcher lines wrap to a new line rather than truncate (law §1.4).
6. AUDIT (Session 6, A1 board) — violations found and fixed
- MovementChip rendered AFTER the grade (market context inside the model slot). Moved to slot 4, before the revision/grade pair.
- ViabilityChips rendered between team and archetype, splitting the identity run. Moved after the archetype badge (identity → viability).
fade-upkeyframe started atopacity: 0— violating the S33 "entrance keyframes floor at the visible state" rule (a paused frame was invisible, and the hero LCP paint was delayed by the animation). Floored at.6. Everything else already conformed: best-price dot precedes the grade, the outcome chip suppresses actions, provenance is last, awaiting rows carry the honest schedule copy.
— ROW-GRAMMAR v1.0 · July 2026 —