Design pass: Protocol AUDIT — DOUB projection (readability + patterns) #235

Closed
opened 2026-05-21 13:21:12 +00:00 by PlasticDigits · 5 comments
PlasticDigits commented 2026-05-21 13:21:12 +00:00 (Migrated from gitlab.com)

Context

DOUB projection shipped on /timecurve/protocol (subnav AUDIT) per GitLab #229. Functional scope is done (251M policy supply, launch-anchor market cap, CHARM→DOUB redemption, Kumbaya USD line, wallet share). This issue is a visual / UX design pass — especially readability and consistency with established TimeCurve protocol patterns — not new economics or RPC reads.

Implementation: TimeCurveProtocolDoubProjectionSection.tsx · shared math doubProjectionStats.ts · protocol refresh row styles (.timecurve-protocol__stat-value-row, .timecurve-protocol__inline-refresh) · timecurve-views §229

Design baseline: docs/frontend/design.md · Sale state TOTAL USD row on same page · Raw contract → Reserve routing and launch anchors accordion parity · Simple rate board alignment


Goals

  1. Readability — ten stat cards covering supply, redemption, clearing/launch/Kumbaya anchors, market cap, live CHARM price, and wallet share must scan in logical clusters without label fatigue.
  2. Pattern match — StatCard meta lines, inline ↻ refresh affordances, USD disclosure, and empty states match Sale state hero / protocol raise card and neighboring Platform usage #231.
  3. Trust — economics labels clearly distinguish clearing vs launch anchor vs Kumbaya floor vs USD illustrative; footnotes/meta not truncated into ambiguity on mobile.

Review checklist

Section chrome

  • PageSection title DOUB projection, badge launch economics, lede length and tone match Platform usage and Sale state sections.
  • Section visible only when sale is live (protocolPhase !== saleStartPending) — pre-open absence does not leave awkward gap vs Sale state block.
  • data-testid="timecurve-protocol-doub-projection" unchanged unless E2E updated.

Stat grid information architecture

  • 10 cards grouped mentally (supply → redemption → price anchors → market cap → live price → wallet share) — consider visual subheadings or grid breaks if flat .stats-grid feels like a wall of numbers.
  • Label copy consistent with accordion Reserve routing and launch anchors (same terms: clearing, launch anchor, Kumbaya band floor).
  • Projected total supply (251M) vs Sale bucket (onchain) relationship obvious — policy constant vs live totalTokensForSale() not confused.
  • CHARM → DOUB at launch meta (Decreases as sale progresses) visible without wrapping into label.

Values + formatting

  • Compact CL8Y/DOUB formatting (formatBuyHubDerivedCompact, formatCompactFromRaw) matches Sale state and Live buys — 4 sigfig policy #191.
  • Implied market cap (CL8Y) vs Implied market cap (USD) visually paired; USD line uses same Kumbaya spot disclosure as protocol TOTAL USD / #192.
  • Kumbaya band floor meta (0.25× launch anchor) matches docs — not confused with older 0.8× copy anywhere on page.
  • Per-CHARM price (live) distinguished from launch redemption rate — operators should not conflate the two at a glance.

Inline refresh affordances

  • ↻ on USD market cap and Your share of sale uses ProtocolInlineRefreshButton consistently with protocol raise TOTAL USD row.
  • Refresh buttons discoverable but not noisy; disabled/loading states clear.
  • .timecurve-protocol__stat-value-row alignment: value + button baseline on mobile.

Empty / gated states

  • EmptyDataPlaceholder for CHARM→DOUB when totalCharmWeight == 0 (INV-FRONTEND-200) — copy (No CHARM minted yet) readable, not mistaken for error.
  • Your share of sale: Connect wallet / Loading / No data yet states match wallet-gated patterns elsewhere.
  • Loading labels on stat cards (Loading clearing…, etc.) consistent length — no layout shift when resolving.

Responsive + a11y

  • ≤479px: .stats-grid wraps without horizontal page scroll; meta lines remain legible.
  • Long stat labels (e.g. Implied CL8Y / DOUB (clearing)) wrap gracefully; no clipped text in card chrome.
  • USD meta title tooltip (PROTOCOL_CL8Y_USD_SPOT_TITLE) sufficient for power users; consider visible footnote if tooltips are easy to miss on touch.

Cohesion with full AUDIT scroll

  • Placed after Sale state — narrative flow: raise totals → projection economics → live activity (Live buys) → Platform usage.
  • Visual weight comparable to Platform usage; neither economics card overwhelms the operator KV blocks below.
  • Expanded accordion values match card rows when operator cross-checks (parity requirement from #229).

Out of scope

  • Changing 251M supply policy, market-cap formula (launch anchor vs clearing), or Kumbaya multiplier constants.
  • External oracle USD feeds beyond existing Kumbaya quoter.
  • Wallet-level projected DOUB holdings (Simple stake panel scope).

Verification

  • Manual visual QA on /timecurve/protocol with sale live (Anvil/devnet/staging) — buy progression updates CHARM→DOUB and clearing-related rows.
  • Cross-check card vs Raw contract → Reserve routing and launch anchors accordion.
  • Compare ↻ / USD disclosure with protocol TOTAL RAISE card on same page.
  • Mobile viewport spot-check (375px, 479px).
  • Existing tests stay green: doubProjectionStats.test.ts, Playwright AUDIT smoke.

Definition of done: checklist items addressed or explicitly waived with comment; CSS/component tweaks merged; no regression to INV-FRONTEND-229-DOUB-PROJECTION behavior.

## Context **DOUB projection** shipped on **`/timecurve/protocol`** (subnav **AUDIT**) per [GitLab #229](https://gitlab.com/PlasticDigits/yieldomega/-/issues/229). Functional scope is done (251M policy supply, launch-anchor market cap, CHARM→DOUB redemption, Kumbaya USD line, wallet share). This issue is a **visual / UX design pass** — especially **readability** and **consistency with established TimeCurve protocol patterns** — not new economics or RPC reads. **Implementation:** [`TimeCurveProtocolDoubProjectionSection.tsx`](frontend/src/pages/timecurve/TimeCurveProtocolDoubProjectionSection.tsx) · shared math [`doubProjectionStats.ts`](frontend/src/lib/doubProjectionStats.ts) · protocol refresh row styles (`.timecurve-protocol__stat-value-row`, `.timecurve-protocol__inline-refresh`) · [`timecurve-views §229`](docs/frontend/timecurve-views.md#timecurve-protocol-doub-projection-gitlab-229) **Design baseline:** [`docs/frontend/design.md`](docs/frontend/design.md) · **Sale state** TOTAL USD row on same page · **Raw contract → Reserve routing and launch anchors** accordion parity · Simple rate board alignment --- ## Goals 1. **Readability** — ten stat cards covering supply, redemption, clearing/launch/Kumbaya anchors, market cap, live CHARM price, and wallet share must scan in logical clusters without label fatigue. 2. **Pattern match** — `StatCard` meta lines, inline **↻** refresh affordances, USD disclosure, and empty states match Sale state hero / protocol raise card and neighboring **Platform usage** [#231](https://gitlab.com/PlasticDigits/yieldomega/-/issues/231). 3. **Trust** — economics labels clearly distinguish **clearing** vs **launch anchor** vs **Kumbaya floor** vs **USD illustrative**; footnotes/meta not truncated into ambiguity on mobile. --- ## Review checklist ### Section chrome - [ ] `PageSection` title **DOUB projection**, badge **launch economics**, lede length and tone match **Platform usage** and **Sale state** sections. - [ ] Section visible only when sale is live (`protocolPhase !== saleStartPending`) — pre-open absence does not leave awkward gap vs Sale state block. - [ ] `data-testid="timecurve-protocol-doub-projection"` unchanged unless E2E updated. ### Stat grid information architecture - [ ] **10 cards** grouped mentally (supply → redemption → price anchors → market cap → live price → wallet share) — consider visual subheadings or grid breaks if flat `.stats-grid` feels like a wall of numbers. - [ ] Label copy consistent with accordion **Reserve routing and launch anchors** (same terms: clearing, launch anchor, Kumbaya band floor). - [ ] **Projected total supply (251M)** vs **Sale bucket (onchain)** relationship obvious — policy constant vs live `totalTokensForSale()` not confused. - [ ] **CHARM → DOUB at launch** meta (*Decreases as sale progresses*) visible without wrapping into label. ### Values + formatting - [ ] Compact CL8Y/DOUB formatting (`formatBuyHubDerivedCompact`, `formatCompactFromRaw`) matches Sale state and Live buys — 4 sigfig policy [#191](https://gitlab.com/PlasticDigits/yieldomega/-/issues/191). - [ ] **Implied market cap (CL8Y)** vs **Implied market cap (USD)** visually paired; USD line uses same Kumbaya spot disclosure as protocol **TOTAL USD** / [#192](https://gitlab.com/PlasticDigits/yieldomega/-/issues/192). - [ ] **Kumbaya band floor** meta (**0.25× launch anchor**) matches docs — not confused with older 0.8× copy anywhere on page. - [ ] **Per-CHARM price (live)** distinguished from launch redemption rate — operators should not conflate the two at a glance. ### Inline refresh affordances - [ ] **↻** on USD market cap and **Your share of sale** uses [`ProtocolInlineRefreshButton`](frontend/src/pages/timecurve/ProtocolInlineRefreshButton.tsx) consistently with protocol raise **TOTAL USD** row. - [ ] Refresh buttons discoverable but not noisy; disabled/loading states clear. - [ ] `.timecurve-protocol__stat-value-row` alignment: value + button baseline on mobile. ### Empty / gated states - [ ] **`EmptyDataPlaceholder`** for CHARM→DOUB when `totalCharmWeight == 0` (**INV-FRONTEND-200**) — copy (*No CHARM minted yet*) readable, not mistaken for error. - [ ] **Your share of sale**: Connect wallet / Loading / No data yet states match wallet-gated patterns elsewhere. - [ ] Loading labels on stat cards (*Loading clearing…*, etc.) consistent length — no layout shift when resolving. ### Responsive + a11y - [ ] ≤479px: `.stats-grid` wraps without horizontal page scroll; meta lines remain legible. - [ ] Long stat labels (e.g. **Implied CL8Y / DOUB (clearing)**) wrap gracefully; no clipped text in card chrome. - [ ] USD meta `title` tooltip (`PROTOCOL_CL8Y_USD_SPOT_TITLE`) sufficient for power users; consider visible footnote if tooltips are easy to miss on touch. ### Cohesion with full AUDIT scroll - [ ] Placed after **Sale state** — narrative flow: raise totals → projection economics → live activity (**Live buys**) → **Platform usage**. - [ ] Visual weight comparable to **Platform usage**; neither economics card overwhelms the operator KV blocks below. - [ ] Expanded accordion values match card rows when operator cross-checks (parity requirement from #229). --- ## Out of scope - Changing 251M supply policy, market-cap formula (launch anchor vs clearing), or Kumbaya multiplier constants. - External oracle USD feeds beyond existing Kumbaya quoter. - Wallet-level projected DOUB holdings (Simple stake panel scope). --- ## Verification - [ ] Manual visual QA on `/timecurve/protocol` with sale live (Anvil/devnet/staging) — buy progression updates CHARM→DOUB and clearing-related rows. - [ ] Cross-check card vs **Raw contract → Reserve routing and launch anchors** accordion. - [ ] Compare **↻** / USD disclosure with protocol **TOTAL RAISE** card on same page. - [ ] Mobile viewport spot-check (375px, 479px). - [ ] Existing tests stay green: [`doubProjectionStats.test.ts`](frontend/src/lib/doubProjectionStats.test.ts), Playwright AUDIT smoke. **Definition of done:** checklist items addressed or explicitly waived with comment; CSS/component tweaks merged; no regression to **`INV-FRONTEND-229-DOUB-PROJECTION`** behavior.
PlasticDigits commented 2026-05-21 13:21:14 +00:00 (Migrated from gitlab.com)

marked as related to #229

marked as related to #229
PlasticDigits commented 2026-05-22 06:04:41 +00:00 (Migrated from gitlab.com)

mentioned in commit 0556c503cc

mentioned in commit 0556c503ccf325027e6840e9ae9096f1dda81e30
PlasticDigits commented 2026-05-22 06:04:41 +00:00 (Migrated from gitlab.com)

mentioned in commit decb5a0829

mentioned in commit decb5a0829b0967b22197711689f10a09990ed6e
PlasticDigits commented 2026-05-22 06:06:34 +00:00 (Migrated from gitlab.com)

Shipped on main (5b8dbe6 / decb5a0)

Presentation-only pass for protocol DOUB projection (GitLab #235):

  • Grouped stat cards: Supply and redemption, Price anchors, Market and wallet lens
  • Responsive CSS (sticky group headers desktop, overflow-wrap mobile)
  • doubProjectionLayoutCss.test.ts regression coverage
  • Docs / invariants / manual QA / guardrails cross-links updated alongside #229

Not merged: older feat/235-doub-projection-design worktree branch (superseded by fix/235-doub-projection-design).

Verification for @nullvector_ux

  • /timecurve/protocol → DOUB projection: three labeled groups, 10 cards, data-testid="timecurve-protocol-doub-projection"
  • Sale live: clearing / launch / Kumbaya floor / per-CHARM live scannable in Price anchors
  • Mobile ~375px: no horizontal scroll in projection block
  • Empty / refresh behavior unchanged vs pre-#235

Issue stays open for design sign-off.

## Shipped on `main` (`5b8dbe6` / `decb5a0`) Presentation-only pass for protocol **DOUB projection** (GitLab #235): - Grouped stat cards: **Supply and redemption**, **Price anchors**, **Market and wallet lens** - Responsive CSS (sticky group headers desktop, `overflow-wrap` mobile) - `doubProjectionLayoutCss.test.ts` regression coverage - Docs / invariants / manual QA / guardrails cross-links updated alongside #229 **Not merged:** older `feat/235-doub-projection-design` worktree branch (superseded by `fix/235-doub-projection-design`). ### Verification for @nullvector_ux - [ ] `/timecurve/protocol` → DOUB projection: three labeled groups, 10 cards, `data-testid="timecurve-protocol-doub-projection"` - [ ] Sale live: clearing / launch / Kumbaya floor / per-CHARM live scannable in **Price anchors** - [ ] Mobile ~375px: no horizontal scroll in projection block - [ ] Empty / refresh behavior unchanged vs pre-#235 Issue stays open for design sign-off.
nullvector_ux commented 2026-05-22 06:59:48 +00:00 (Migrated from gitlab.com)

@PlasticDigits

Verification for @nullvector_ux

  • /timecurve/protocol → DOUB projection: three labeled groups, 10 cards, data-testid="timecurve-protocol-doub-projection"
  • Sale live: clearing / launch / Kumbaya floor / per-CHARM live scannable in Price anchors
  • Mobile ~375px: no horizontal scroll in projection block
  • Empty / refresh behavior unchanged vs pre-#235
### @PlasticDigits ### Verification for @nullvector_ux * [x] `/timecurve/protocol` → DOUB projection: three labeled groups, 10 cards, `data-testid="timecurve-protocol-doub-projection"` * [x] Sale live: clearing / launch / Kumbaya floor / per-CHARM live scannable in **Price anchors** * [x] Mobile \~375px: no horizontal scroll in projection block * [x] Empty / refresh behavior unchanged vs pre-#235
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-05-25 01:41:22 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega#235
No description provided.