D1-A: combat glyphs, boundary-channel blue, reaction primitives, READ-FAB
Additive frontend/visual. Backend untouched (git diff src/ = empty): no grade,
model, classifier or ledger change. The 41->74 registry expansion is HELD for
D1-B. Push scoring untouched.
REVIEW ZERO — classifier coverage bounded the glyph wiring. Three buckets, and
the computation was redone three times before it was right (the frontend keys
GLYPHS by ARCHETYPE NAME while the backend keys `glyph:` by SHAPE NAME, and most
registry keys are unquoted identifiers — the first two passes mis-parsed both):
(a) classifier-backed, already wired: 38
(b) classifier-backed, package SVG exists, NOT wired -> WIRED HERE: 6
striker, grappler, pressure, counter, grinder, finisher — all MMA/combat
archetypes in archetypeService.js that were rendering EMOJI fallbacks
('*', 'x', '>', '<>') where the package ships real 24-grid duotone marks.
(c) package SVG with no classifier -> HELD for D1-B: 39 (wiring them would
render nothing)
(d) classifier-backed but NO package SVG: 2 ('dual threat', 'paint boss') —
a DESIGN gap, not a build gap; flagged for D1-B.
GLYPHS map 38 -> 44 keys, deliberately far short of the package's 83.
BOUNDARY CHANNEL — the blue tokens already existed (--priced-out set) and were
applied on NoMarketState and the scan void box, but PriceTriplet's NO_MODEL
("line not priced") still rendered in neutral text, so the channel was applied
inconsistently. NO_MODEL now renders in the channel, completing "every boundary
state or none". Token-only (no hex fallback and no hex in prose — PriceTriplet's
own test forbids literal hex, and it caught both).
REACTION PRIMITIVES — new web/src/lib/reactions.js + globals.css keyframes at the
exact HANDOFF timings: flash .75s ease-out, boot stagger 60ms steps, reactions
gated 1.5s, WIRE hold 6s. nudge() REFUSES a no-op (null/absent direction -> no
flash) so the primitive cannot be attached to an idle loop — a flash without a
new datum is the UI lying about the feed. Reduced-motion honoured.
READ-FAB — aligned to the exact package geometry: 50px circle, translateY(-14px),
6px void ring (was 46px, marginTop -16, 3px ring).
CARD TOKEN — audit correction: #0E0E14 was already tokenised as --bg-1/--card;
the audit's "1 file" was counting the raw hex, not the token. No change needed.
Floor: 317 suites / 3946 tests green (16 new), web build exit 0.
NOT DONE THIS ORDER (reported, not silently dropped): row-hover rationale and
IntersectionObserver reveal (Phase 3 item 8) and team-gradient chips (Phase 4
item 10) are not implemented — they need the System artboard's row anatomy,
which is a larger port than the rest of D1-A.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QJs13VsyiSKYQP6rj3NNmc
This commit is contained in:
@@ -1532,3 +1532,28 @@ html[data-font="readable"] .wm::after { opacity: 0.45 !important; }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.stamp-in, .grade-reveal > div > * { animation: none !important; }
|
||||
}
|
||||
|
||||
|
||||
/* ============================================================================
|
||||
D1-A REACTION PRIMITIVES (2026-07-31) — exact HANDOFF timings.
|
||||
LAW: "Alive = punctuated stillness (react to truth, then rest)." These fire on
|
||||
DATA EVENTS ONLY. Never attach them to an idle loop — a value that flashes
|
||||
without new data is the animation lying about the feed.
|
||||
============================================================================ */
|
||||
|
||||
/* nudge(cell, up) — value update flash, .75s ease-out, edge recolours by sign. */
|
||||
@keyframes rx-up { 0% { background: rgba(0,212,160,.22); } 100% { background: transparent; } }
|
||||
@keyframes rx-down { 0% { background: rgba(255,71,87,.22); } 100% { background: transparent; } }
|
||||
.rx-up { animation: rx-up .75s ease-out 1; }
|
||||
.rx-down { animation: rx-down .75s ease-out 1; }
|
||||
|
||||
/* Boot: rows stagger in at 60ms steps, hero arrives last. */
|
||||
@keyframes vy-rowin { from { opacity: .6; transform: translateY(4px); } to { opacity: 1; transform: none; } }
|
||||
@keyframes vy-arrive { from { opacity: .6; transform: scale(.985); } to { opacity: 1; transform: none; } }
|
||||
.vy-rowin { animation: vy-rowin .28s ease-out both; }
|
||||
.vy-arrive { animation: vy-arrive .42s ease-out both; }
|
||||
|
||||
/* Reduced motion: the entrance floors at the VISIBLE state, never invisible. */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.rx-up, .rx-down, .vy-rowin, .vy-arrive { animation: none; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user