Young's Mind
Product Spec

Pulse V2 — Design Spec (Nova)

Companion to: PULSE-V2-SPEC.md (product spec, Min) · Status: v1.0 design layer Scope: wireframes, component tree, design tokens, interaction & feedback patterns, a11y Constraint honored: V1 tokens unchanged (dark #09090b, mint #16A34A) — V2 is a layout/data upgrade, not a rebrand.

Pulse V2 — Design Spec (Nova)

Companion to: PULSE-V2-SPEC.md (product spec, Min) · Status: v1.0 design layer Scope: wireframes, component tree, design tokens, interaction & feedback patterns, a11y Constraint honored: V1 tokens unchanged (dark #09090b, mint #16A34A) — V2 is a layout/data upgrade, not a rebrand.


🎨 1. Component Architecture & Friction Mapping

Page: / Dashboard

┌──────────────────────────────────────────────────────────────────────┐
│ HEADER  🧠 Pulse   [ ⌕ Search ticker…        ]   Dashboard·News·Ask AI│
├──────────────────────────────────────────────────────────────────────┤
│ INDEX STRIP  ASX200 ▲0.6% · ASX100 · ASX50 · AllOrds · S&P500 ·      │
│              Dow · Nasdaq · VIX        ← 8 chips, horiz. scroll mob. │
├────────────────────────────────────────┬─────────────────────────────┤
│ MAIN (8 cols)                          │ RIGHT RAIL (4 cols, sticky) │
│ 1. Top Market News  (3-4 headlines)    │ 1. Watchlist  (live ▲▼)     │
│    source badge + rel. time            │    WEB·DRO·SEMI… + portfolio│
│ 2. Movers  (top3 ▲ / top3 ▼)           │ 2. Markets (AU·US·EU·Asia)  │
│    two-column, % first, then price     │ 3. MA50 Alerts (existing)   │
│ 3. Daily Brief card → /news            │                             │
└────────────────────────────────────────┴─────────────────────────────┘

Friction decisions (why the layout wins)

DecisionFriction removed
Index strip above everythingMarket state readable in <1s — the "one glance" promise. 8 fixed slots, no discovery cost.
Right rail stickyWatchlist stays visible while scrolling news — Young's core loop is check holdings while reading.
Movers: % as primary, $ secondaryTraders scan % first; price is confirm-only. Colour + size both encode %.
Two-column movers (▲/▼)No sort toggle = no state to manage. Gainers left, losers right, done.
Search centered in headerSingle entry to any ticker; /stock/<TICKER> is always 1 keystroke away.
Rail cards stack, never grid on mobileVertical scan on phone; nothing below fold is critical.

Page: /stock/[ticker]

Breadcrumb  Dashboard / SEMI
┌──────────────────────────────────────────────────────────────────┐
│ SEMI  $X.XX  ▲ +1.2%      [1D 1W 1M 6M 1Y All]  ← timeframe chips│
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │  TradingView chart (MA50 + volume)     ← existing component  │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ KEY STATS grid (2×4 desktop / 2-col mobile): open·high·low·prev  │
│ close·52w range·avg vol·mkt cap·P/E·yield                        │
│ MA50 STATUS: D ▲ W ▲ (signal engine)  ·  distance to watch levels│
│ TICKER NEWS: Google-News site-scoped list, source + time         │
└──────────────────────────────────────────────────────────────────┘

Friction: everything about one ticker is one viewport deep — price/chart/stats/news with zero tabs. Breadcrumb back is the only nav chrome.

Page: /heatmap

25-cell universe grid, colour = daily % (green/red scale), size = weight in universe. Cell shows ticker + %; hover/focus reveals price. Click → /stock/[ticker].

Component tree (build order = dependency order)

app.vue (header + search + nav)
├─ IndexStrip          (8 slots, horizontal scroll, live dot)
├─ SearchBox           (universe-filter autocomplete → navigate)
├─ Dashboard:
│  ├─ MoversCard       (props: gainers[3], losers[3])
│  ├─ NewsHeadlines    (props: items[4]; reused on /news)
│  ├─ DailyBriefCard   (link → /news)
│  ├─ WatchlistRail    (props: quotes[]; row = ticker·price·chg·spark)
│  ├─ MarketsCard      (regional index mini-cards)
│  └─ Ma50AlertsCard   (existing, restyled to tokens)
└─ /stock/[ticker]:
   ├─ PriceHeader      (price, change, timeframe chips)
   ├─ TradingViewChart (EXISTING — do not modify)
   ├─ StockStats       (props: stats{}; label-value grid)
   ├─ Ma50Status       (D/W badge + distance-to-levels)
   └─ TickerNews       (props: news[])

🎚 2. Design Token System Alignment

Zero new palette. V1 system carries V2 (spec §4 mandates it):

TokenValueV2 usage
--bg#09090bpage surface
--color-cardglass card (rgba + blur)all cards incl. rail
--color-edgeborder tokencard + strip chip borders
--accent#16A34A mintMA50 badges, links, focus rings, Ask AI
up / down#22c55e / #ef4444AU convention: green=up (Young trades ASX)
fontInterstat numerals use tabular-nums — columns never jitter on refresh
spacing4/8 grid; rail gap 8px, card gap 16pxdense GF-feel without crowding
loadingshimmer skeleton (V1 pattern)every card pre-data

Numerals rule: all prices/percentages render font-variant-numeric: tabular-nums at fixed width — this is what makes live-updating rows feel like a terminal, not a spreadsheet shuffle.

Contrast: change% text minimums — #22c55e/#ef4444 on #09090b both pass 4.5:1; chip labels use --text-secondary ≥ #a1a1aa.


📡 3. Micro-Interaction & Telemetry Feedback Loops

SignalPattern
Live datapulsing mint dot on IndexStrip + WatchlistRail header; dot goes amber if /api/quotes errors twice → title tooltip "cached"
Price changeflash-on-update: row bg tints #22c55e/#ef4444 8% for 600ms on delta (CSS class toggle, no JS anim lib)
Loadingshimmer skeletons per-card (never full-page spinner) — partial data renders as it arrives
Chart timeframechips: active = mint text + underline, hover = edge brighten; chart swaps via existing component, no remount flicker
Search⌕ opens instantly (no route change); type ≥1 char filters universe; Enter navigates /stock/<T>; Esc closes
MA50 badgeD/W states: ▲ mint / ▼ red / — grey; grey = stale data, not "neutral signal" (honest telemetry)
Sticky rail on mobilecollapses to horizontal swipe cards above Main (watchlist first — it's the glance surface)

A11y: all interactive cells keyboard-reachable (heatmap = buttons, arrow-nav optional V3); change% never encoded by colour alone — arrow glyph ▲▼ always present; focus ring = 2px mint.


Ownership & acceptance

  • All components in spec §5 ownership split; Nova owns everything above, TradingViewChart is the only touch-not (existing, proven).
  • Acceptance = spec §6 checkboxes; design adds: tabular-nums verified on 3-price refresh, mobile rail swipe, skeleton→data swap without layout shift (CLS ≈ 0).
  • Build order: SearchBox → IndexStrip → rail cards → dashboard assembly → /stock/[ticker] → heatmap. Estimated first shippable: dashboard + strip.
Copyright © 2026