Design train: capture Design's drawn mobile + reconcile M1a to it

Design now provides mobile designs (Vyndr Mobile.dc.html, 5 screens at 390×844).
Captured as specs/design-reference/MOBILE-SPEC.md — the buildable distillation
(the raw dc-runtime HTML needs React to render; the design project holds the
verbatim source). I'm now IMPLEMENTING Design's mobile, not inferring it.

RECONCILE of the already-shipped M1a against Design's mobile:
- EKG hidden <768px — Design AGREES (mobile app bar carries no EKG). KEPT.
- .vbtn 44px tap target — Design AGREES (buttons are 44/46px). KEPT.
- .m-hero generic clamp — CONFLICT. Design uses CONTEXT-SPECIFIC hero sizes
  (74px grade tier / 40px live tier / 24px /u stats), not one clamp, and
  nothing consumed the class. REMOVED; the specific sizes land per-surface in M1b.
- Mobile HEADER shape — Design OVERRIDES: mobile is an app bar (logo + sync
  clock) + a breadth strip + a bottom wire, NOT the collapsed heartbeat bar.
  The EKG-drop is a compatible interim step; the full app-bar recomposition is
  M1b (the board/shell surface). Flagged in the CSS + MOBILE-SPEC.

Built to Design's mobile spec, VISUALLY UNVERIFIED at 390px (Chrome audit is eyes).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-07-16 11:03:12 -04:00
parent b1138eac5e
commit c4d4617fab
2 changed files with 78 additions and 16 deletions
+65
View File
@@ -0,0 +1,65 @@
# VYNDR MOBILE — Design's authoritative 390×844 spec
### Distilled from `Vyndr Mobile.dc.html` (claude.ai/design project 370ba6df, "Vyndr Mobile.dc.html"). Design DREW mobile — build to THIS, don't infer from principles. The raw dc-runtime HTML lives in the design project (it needs React/support.js to render, so this faithful distillation is the buildable reference). Tokens unchanged (green #00D4A0, miss #FF4757, amber #FFB347, text #F0F0F0/#B8BCC8/#707080/#4a4a58, bg #06060B/#0A0A10/#0E0E14/#14141E).
Design's one line: "Same tokens, same ranked density, same earned motion — recomposed for thumbs. Tab bar owns navigation; one hero per screen survives the shrink."
## GLOBAL MOBILE HEADER — an APP BAR, not the desktop header stack
The desktop Nav + Ticker + HeartbeatBar does NOT carry to mobile. Design replaces it with a compact **app bar** (one row):
- Left: 24px logo mark + `VYND⟨R green⟩` wordmark (mono, 14px, .26em, glitch 6.5s).
- Right: a small green **sync dot** (pulse) + **sync clock** `HH:MM:SS` (mono, 10px, #B8BCC8).
- 10px vertical padding, `border-bottom:1px solid #14141E`. NO EKG, NO ticker, NO "SIGNAL LIVE · N graded · SYNC" here.
The live "wire"/ticker is moved to the **BOTTOM** of the board (above the tab bar), and the market breadth is its own strip below the app bar. So the header is genuinely one clean line.
## GLOBAL — BOTTOM TAB BAR (5 tabs)
Design's tabs: **BOARD · STREAKS · BUILD · LEDGER · /u**. Icons 20px, labels mono 7.5px .12em, active = green (#00D4A0), inactive = #707080. NOTE the delta vs the live app (Slate/Explore/Scan/Ledger/More): Design has no separate Scan tab or raised FAB — "BUILD" is the slip. **This is a nav-structure decision to confirm with Kev before changing (Scan-5 is monetization-critical) — flagged, not auto-applied.**
## SCREEN 01 · TERMINAL (the board / dashboard-slate) — the anchor surface
Stack, top→bottom, full 390 width:
1. **App bar** (above).
2. **Breadth strip**: `EDGES 14 · AVG CLV +2.8% · 47 GAMES` — mono 9.5px labels (#707080), values bold (edges #F0F0F0, CLV green), GAMES pushed right (`margin-left:auto`). border-bottom.
3. **EDGE BOARD** header row: `EDGE BOARD` (mono 10px .24em bold) + sort chip `EDGE ▼` (mono 8.5px #707080).
4. **Ranked rows** — THE core mobile grammar. Each row: `[rank] [name + prop | sport·matchup] [grade chip] [edge%]`, `padding:11px 16px`, `border-top:1px solid #101018`:
- rank: mono 10px, 16px wide; **#1 is green**, rest #707080.
- identity: name 13px 700 + `o27.5 PTS` in #B8BCC8 500; sub-line mono 8px .1em #707080 = `NBA · DEN @ MIN` (green if LIVE, with a live-dot before the name).
- grade chip: mono 10px 800, 17px tall, `padding:0 6px`, tier-colored (A+/A green tint+green border, B `#14141E`/#F0F0F0, D red tint+red border).
- edge%: mono 12px 700, 48px right-aligned, **green if +, #FF4757 if ** (the one hero figure per row).
- **RANKING VISIBLE VIA OPACITY:** rows fade down the list — 01/02 full, 03 (live), 04 `.85`, 05 `.7`, 06 `.55`. Top edges carry a green left inset border (`box-shadow:inset 2px 0 0 rgba(0,212,160,.55)` for #1, `.4` for #3).
5. **WIRE** (the ticker, relocated to bottom): `WIRE` label (green 8px .22em 800) + one scrolling line (mono 9.5px #B8BCC8, ellipsis), on `#08080D`, border-top. Cycles STEAM/LIVE/FLAG/FADE every 6s.
6. **Tab bar** (above).
## SCREEN 02 · GRADE REVEAL
Header: `◂ BOARD` (11px #B8BCC8) + `CLV-VERIFIED` (9px .2em green). Body `padding:22px 18px`:
- `DECLASSIFIED · TOP GRADE` (mono 9.5px .26em #707080).
- **Hero row**: giant `A+` (mono **74px**, .82 line, green, `text-shadow:0 0 30px rgba(0,212,160,.5)`) + `TIER` label under it; beside it the identity block — team monogram chip (34px, team-gradient), `Nikola Jokić` 14.5px 700, `C · DEN · CONFIRMED` (mono 9px, CONFIRMED in #B8BCC8), `Over 27.5 Points` 14px, then `DK -114 ▲ opened 25.5` (mono 10px, ▲ green).
- **Line-movement sparkline**: full-width SVG polyline (green, area fill), with `OPEN 25.5 · STEAM ▲ · NOW 27.5` under it (8px, STEAM green).
- **3-col stat grid** (1px gaps on #1E1E2A, radius 10): `EDGE +8.4%` (green), `L10 HIT 8/10`, `PROJ 30.8` — labels mono 8.5px .16em #707080, values mono 17px 800.
- **VYNDR INTELLIGENCE** box (`#0A0A10`, border #14141E): dot + label (mono 8.5px .22em #B8BCC8), then a prose sentence 12px #B8BCC8 with mono/green emphasis on the numbers + archetype name.
- Buttons: `SHARE THE READ` (green fill, 46px, mono 11.5px 800) + `ADD TO SLIP` (outline #2A2A38, 44px).
## SCREEN 03 · BUILD (parlay slip)
Header `PARLAY SLIP` + `2 LEGS`. Body `padding:14px 16px`:
- **Leg rows**: green check chip (20px) + `Jokić o27.5 PTS` 13.5px + `NBA · DEN @ MIN` mono 8.5px + grade chip + american odds (`+105`). Card `rgba(0,212,160,.05)`, border #1E1E2A, green left inset border, radius 12.
- **SAME-GAME CORRELATION** warning (amber): triangle icon + `SAME-GAME CORRELATION` (8.5px amber 700) + explanation (mono 9.5px #B8BCC8) on `rgba(255,179,71,.08)` border amber.
- **3-col**: `COMBINED +371` (#F0F0F0) · `GRADE A-` (amber) · `STAKE 0.4u` (amber).
- **ADD FROM TONIGHT'S A/B READS**: empty-checkbox rows (Skenes/Judge, #B8BCC8, odds).
- Footer button `TRACK SLIP · 0.4u` (green fill 46px).
## SCREEN 04 · LOCK SCREEN · LIVE ACTIVITY (iOS-native concept — ASPIRATIONAL)
An iOS lock screen: dynamic-island pill (`Edwards A ●`), 76px clock, a **Live Activity card** (VYNDR + `LIVE · Q3 4:12`, 40px live `A`, `Edwards o5.5 AST`, `4 AST · pacing ▲ · usage +6%`, a 6-seg progress bar `4 OF 6 · NEEDS 2 · 16 MIN LEFT`), + a STEAM ALERT notification. Closing line `THE TERMINAL WATCHES WHILE YOU DON'T`. **This is a native iOS Live Activity / push concept, NOT a web surface — treat as product-vision, not an M1b web build. The web analog is the in-app live tracker (already exists, StatStrip.LiveTracker); flag the Live Activity as a native/PWA-push future.**
## SCREEN 05 · /u RECORD (the shareable profile)
Body `padding:18px`:
- **Identity**: 54px green-gradient monogram `EH` + `@edgehunter` 17px 800 + `CLV-VERIFIED` badge (green, dot) + `412 graded` (mono 9px #707080).
- **2×2 stat grid** (1px gaps #14141E, radius 12, cells #0C0C12): `HIT RATE 64.2%` (green) · `UNITS +38.6u` (green) · `ROI +11.4%` (#F0F0F0) · `AVG CLV +3.1%` (#F0F0F0). Labels mono 8.5px .16em; values mono **24px 800** .9 line.
- **GRADE HISTORY · L18** with HIT/MISS legend (green/red squares); a 6-col grid of grade cells (aspect-1, tinted by hit/miss, grade letter colored by tier).
- **ARCHETYPE FINGERPRINT**: labeled bars — `TORCH 32%` (#FF6B4A), `BOMBER 24%` (#FF9F45), `ALPHA 18%` (#7C5CFF) — name+% row over a 5px track with a colored fill.
- Footer `SHARE MY RECORD` (green fill 46px).
## MOTION (mobile) — unchanged discipline
sync-dot pulse (1.4s), live-dot (1.5s) only on genuinely-live rows, wire cycles 6s, `data-react` values flash green-up/red-down on change (3s demo cadence). Glitch ONLY on the wordmark. Data never glitches.
## RECONCILE NOTES vs M1a (2026-07-16)
- EKG hidden <768px → Design AGREES (no EKG on mobile). KEEP.
- `.vbtn` 4446px tap target → Design AGREES (buttons are 44/46px). KEEP.
- M1a kept a collapsed heartbeat BAR on mobile → Design OVERRIDES: mobile has an app bar (logo + sync clock) + a separate breadth strip + a bottom wire, NOT the heartbeat bar. The full mobile-header recomposition is an M1b task (the board/shell surface).
- `.m-hero` generic clamp(2856px) → Design uses CONTEXT-SPECIFIC hero sizes (74px grade tier, 40px live tier, 24px /u stats). The generic clamp doesn't match and nothing consumed it → REMOVE `.m-hero`; apply Design's specific sizes per surface in M1b.
+13 -16
View File
@@ -1363,18 +1363,18 @@ html[data-font="readable"] .wm::after { opacity: 0.45 !important; }
/* ============================================================ /* ============================================================
DESIGN COMPLETION TRAIN — M1 MOBILE FOUNDATION (2026-07-16) DESIGN COMPLETION TRAIN — M1 MOBILE FOUNDATION (2026-07-16)
The mockup (specs/design-reference/vyndr-system.html) is DESKTOP-ONLY. Now RECONCILED against Design's drawn mobile (specs/design-reference/
These rules are the deliberate 390px expression of its grammar — not a MOBILE-SPEC.md — Design DREW 390×844, so these implement it, not infer it).
shrink: ONE animated element in the header (DESIGN-SPEC §4), one bold Design agrees: no EKG on mobile, ≥44px tap targets. Design OVERRIDES the
mono hero per card with muted context (§3/§5), ≥44px primary tap targets, header shape — mobile is an app bar (logo + sync clock) + breadth strip +
zero horizontal overflow. BUILT TO SPEC, VISUALLY UNVERIFIED at 390px bottom wire, not the collapsed heartbeat bar; that full recomposition is
(WSL2↔Chrome unreachable here — a true-390px Chrome audit is the eyes). M1b (the board/shell surface). Built to Design's mobile spec, but still
VISUALLY UNVERIFIED at 390px (WSL2↔Chrome unreachable — Chrome audit is eyes).
============================================================ */ ============================================================ */
/* Header-zone collapse (audit: ticker + SIGNAL LIVE + STALE all stacking in /* Header EKG drop <768px — Design's mobile has no EKG (app bar carries only
~110px on narrow). The EKG is decorative proof-of-life — dropped on phones logo + sync clock). Interim step until the full app-bar recomposition in
so the heartbeat reads as ONE clean status line, and the ticker + live-dot M1b; keeps the heartbeat from reading as the audit's stacked 110px zone. */
become the single animated element in the header. */
@media (max-width: 767px) { @media (max-width: 767px) {
.hb-ekg { display: none !important; } .hb-ekg { display: none !important; }
.heartbeat-bar { .heartbeat-bar {
@@ -1399,12 +1399,9 @@ html[data-font="readable"] .wm::after { opacity: 0.45 !important; }
} }
} }
/* Mono hero grammar (§3 "one bold hero figure among muted context"). Card /* (removed .m-hero — RECONCILE 2026-07-16: Design's mobile uses CONTEXT-
hero numbers opt in via .m-hero; they scale up on phones so the ONE figure SPECIFIC hero sizes, not one generic clamp: 74px grade tier, 40px live
that matters dominates the stacked card. Context stays demoted. */ tier, 24px /u stats. Those land per-surface in M1b, not as a global class.) */
@media (max-width: 640px) {
.m-hero { font-size: clamp(28px, 12vw, 56px) !important; line-height: 1; }
}
/* ============================================================ /* ============================================================
Session 60 (night2/E) — §7 reveal choreography. Session 60 (night2/E) — §7 reveal choreography.