@trading-game/design-intelligence-layer 0.13.3 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -57,7 +57,7 @@ cp node_modules/@trading-game/design-intelligence-layer/guides/rules/design-syst
57
57
  3. **Design principles and accessibility first** — every screen must reflect the 8 design principles and meet the accessibility standards (WCAG 2.1 AA). Run both checklists before shipping.
58
58
  4. **No separate installs** — do not install `lucide-react`, `tailwindcss`, or other bundled dependencies separately.
59
59
  5. **After a version bump** — re-copy the rules file into `.cursor/rules/`, check for stale local component copies, and align them with the package.
60
- 6. **Blocks are playground-only** — Blocks (e.g. NavBar) appear in the playground's Blocks tab but are **not** exported from the package. Do not try to import them. To build a block pattern in a consuming project, compose it manually using package components and design tokens. See `guides/design-system-guide/trading-game-ds-guide.md` Section 8.5.
60
+ 6. **Blocks are first-class exports** — Blocks (Hero, Auth, FAQ, NavBar, HeaderNavigation, OpenPositions, Result) are exported from the package the same as primitives. Import them by name and pass data via props. See the `## Blocks` section below for the full catalog.
61
61
 
62
62
  ---
63
63
 
@@ -69,3 +69,142 @@ cp node_modules/@trading-game/design-intelligence-layer/guides/rules/design-syst
69
69
  - Personas: `node_modules/@trading-game/design-intelligence-layer/guides/personas/trading-game-player-field-guide.md`
70
70
  - Brand voice: `node_modules/@trading-game/design-intelligence-layer/guides/brand-voice/trading-game-brand-voice.md`
71
71
  - Full agent rules: `node_modules/@trading-game/design-intelligence-layer/guides/rules/design-system-consuming-project.mdc`
72
+
73
+ ---
74
+
75
+ ## Blocks
76
+
77
+ The package ships eight opinionated, composed blocks alongside the UI primitives. Each block is a single `import` away and accepts data via props. Variants are modeled as a `variant` / `layout` / `mode` prop on one block, not as separate components.
78
+
79
+ ### `HeroBlock`
80
+
81
+ Marketing hero section with centred or split-column layout.
82
+
83
+ ```tsx
84
+ import { HeroBlock } from "@trading-game/design-intelligence-layer"
85
+
86
+ <HeroBlock
87
+ layout="centered" // "centered" | "split"
88
+ tagline={{ label: "What's new", suffix: "v2.0" }}
89
+ heading="Solve your customer's main problem"
90
+ body="One or two sentences expanding on the value prop."
91
+ primaryCta={{ label: "Get started", onClick: ... }}
92
+ secondaryCta={{ label: "Learn more", onClick: ... }} // split layout only
93
+ />
94
+ ```
95
+
96
+ ### `AuthBlock`
97
+
98
+ Sign-in / sign-up form with OAuth providers, divider, email input, terms, and cross-link.
99
+
100
+ ```tsx
101
+ import { AuthBlock } from "@trading-game/design-intelligence-layer"
102
+
103
+ <AuthBlock
104
+ mode="sign-in" // "sign-in" | "sign-up"
105
+ logoSrc="/path/to/brand-icon.svg"
106
+ providers={["google", "telegram", "x"]} // default: all three
107
+ onSubmit={({ email }) => { ... }}
108
+ crossLinkHref="/auth/signup"
109
+ />
110
+ ```
111
+
112
+ ### `FAQBlock`
113
+
114
+ Eyebrow + heading + intro + accordion + optional "Need more help" card.
115
+
116
+ ```tsx
117
+ import { FAQBlock } from "@trading-game/design-intelligence-layer"
118
+
119
+ <FAQBlock
120
+ layout="desktop" // "desktop" | "mobile"
121
+ items={[{ value: "q1", question: "...", answer: "..." }, ...]}
122
+ intro={<>Optional intro paragraph with a <Link>link</Link>.</>}
123
+ helpCard={{ title: "Need more help?", body: "...", ctaLabel: "Contact us" }}
124
+ />
125
+ ```
126
+
127
+ ### `NavBarBlock`
128
+
129
+ Responsive marketing nav with brand mark, link buttons, sign-in/up CTAs, and an internal mobile drawer.
130
+
131
+ ```tsx
132
+ import { NavBarBlock } from "@trading-game/design-intelligence-layer"
133
+
134
+ <NavBarBlock
135
+ brand={{ fullLogoSrc: "...", iconLogoSrc: "...", alt: "Brand" }}
136
+ links={[{ label: "Products" }, { label: "Docs" }, ...]}
137
+ signIn={{ onClick: ... }}
138
+ signUp={{ onClick: ... }}
139
+ />
140
+ ```
141
+
142
+ ### `HeaderNavigationBlock`
143
+
144
+ In-app trading header (back · badge · balance · history · action slot). History icon supports an overlaid count badge in `bg-primary`.
145
+
146
+ ```tsx
147
+ import { HeaderNavigationBlock } from "@trading-game/design-intelligence-layer"
148
+
149
+ <HeaderNavigationBlock
150
+ onBack={() => router.back()}
151
+ badge={{ label: "Demo", variant: "fill-warning" }}
152
+ balance={{ amount: "1000.00", currency: "USDT" }}
153
+ history={{ count: 5, onClick: openHistorySheet }} // count 0 hides badge; >99 shows "99+"
154
+ actions={<SoundToggleButton />}
155
+ />
156
+ ```
157
+
158
+ ### `OpenPositionsBlock`
159
+
160
+ Responsive Sheet (desktop) / Drawer (mobile) containing a list of game positions. Positions are a discriminated union by `kind`: `"rise-fall" | "swipe" | "box-o" | "digits"`.
161
+
162
+ ```tsx
163
+ import { OpenPositionsBlock, Position } from "@trading-game/design-intelligence-layer"
164
+
165
+ const positions: Position[] = [
166
+ { kind: "rise-fall", direction: "Rise", market: "Vol 100", duration: "30 minutes",
167
+ stake: "1.00 USDT", pnl: "+0.96 USDT", win: true },
168
+ ...
169
+ ]
170
+
171
+ <OpenPositionsBlock
172
+ trigger={<Button variant="secondary">Active trades</Button>}
173
+ positions={positions}
174
+ sheetTitle="Positions"
175
+ onViewHistory={openHistoryPage}
176
+ />
177
+ ```
178
+
179
+ ### `ResultBlock`
180
+
181
+ Universal win/loss result card with animated halo + thumb illustration + contract badge + duration badge + CTA. Thumb icons are bundled inside the package.
182
+
183
+ ```tsx
184
+ import { ResultBlock } from "@trading-game/design-intelligence-layer"
185
+
186
+ <ResultBlock
187
+ status="win" // "win" | "loss"
188
+ amount="10,000.00"
189
+ currency="USDT"
190
+ contractLabel="Rise"
191
+ duration="2 hours"
192
+ pickedDigit={7} // optional, for Digits contracts
193
+ ctaMode="next-round" // "next-round" | "go-again" | "conversion"
194
+ />
195
+ ```
196
+
197
+ ### `ResultDialog`
198
+
199
+ Fixed-width system dialog (title + body + two CTAs). Used for messages like "out of balance".
200
+
201
+ ```tsx
202
+ import { ResultDialog } from "@trading-game/design-intelligence-layer"
203
+
204
+ <ResultDialog
205
+ title="You're out of balance."
206
+ body="Deposit to keep playing or stay in demo mode."
207
+ primaryLabel="Deposit now"
208
+ secondaryLabel="Stay in demo"
209
+ />
210
+ ```
package/README.md CHANGED
@@ -159,14 +159,24 @@ npm install react react-dom tailwindcss
159
159
 
160
160
  ## Blocks
161
161
 
162
- Blocks are pre-composed UI patterns built from design system primitives. They are demonstrated in the **Blocks** tab of the development playground and are **not** exported from the npm package import the underlying components directly if you need to use them.
162
+ Blocks are opinionated, composed UI patterns built from design system primitives **exported from the package the same as primitives**. Import them by name and pass data via props. Variants (`layout` / `mode` / `status`) live on a single block, not separate components.
163
+
164
+ ```tsx
165
+ import { HeroBlock, ResultBlock, OpenPositionsBlock } from "@trading-game/design-intelligence-layer"
166
+ ```
163
167
 
164
168
  | Block | Variants | Description |
165
169
  |---|---|---|
166
- | NavBar | Desktop, Mobile (closed), Mobile (open) | Landing page top navigation bar. Logo + ghost nav links (Products, Use Cases, Docs, Blog, FAQ) + Sign in / Sign up CTAs. |
167
- | Hero | Type 1 (Desktop + Mobile), Type 2 | Landing page hero sections. Type 1: tagline pill + heading + body + CTAs left, image right (responsive). Type 2: centred single-column, tagline pill + heading + body + primary CTA with arrow icon, no image. |
168
- | Sheet Open Positions | Active, Empty | Right-side sheet (desktop) / bottom drawer (mobile) listing open trading positions. Active state shows a scrollable position list with win/loss colouring and a history footer link. Empty state shows an empty state illustration. |
169
- | Header navigation | — | Product app top header bar. Back navigation button left, account balance + Demo badge centre, history and sound action buttons right. |
170
+ | `HeroBlock` | `layout: "centered" \| "split"` | Marketing hero section. Centred = single-column, no image; split = two-column with image. Tagline pill, heading, body, primary + optional secondary CTA. |
171
+ | `AuthBlock` | `mode: "sign-in" \| "sign-up"` | Auth form logo lockup, OAuth provider buttons (Google, Telegram, X), divider, email input, terms, primary CTA, footer cross-link. |
172
+ | `FAQBlock` | `layout: "desktop" \| "mobile"` | Eyebrow + heading + intro + accordion + optional "Need more help" card. Items passed as `{ value, question, answer }[]`. |
173
+ | `NavBarBlock` | — (internal mobile-menu state) | Responsive marketing nav brand logos, link buttons, Sign in / Sign up CTAs, hamburger drawer on mobile. |
174
+ | `HeaderNavigationBlock` | — | In-app trading header. Back · badge · balance · optional history button with `history.count` numeric badge (`bg-primary`; ≥99 → `99+`) · actions slot. |
175
+ | `OpenPositionsBlock` | `Position` discriminated union (`rise-fall` / `swipe` / `box-o` / `digits`) | Responsive Sheet (desktop) / Drawer (mobile) listing open positions. Consumer-provided trigger; default empty state. |
176
+ | `ResultBlock` | `status: "win" \| "loss"`, `ctaMode: "next-round" \| "go-again" \| "conversion"` | Win/loss result card. Animated halo + thumb illustration (bundled inline) + contract badge + duration badge + CTA. |
177
+ | `ResultDialog` | — | Fixed-width system dialog (title + body + two CTAs). For messages like "out of balance" or "on a roll". |
178
+
179
+ See [`AGENTS.md`](./AGENTS.md#blocks) for full usage examples per block.
170
180
 
171
181
  ---
172
182
 
@@ -215,6 +225,9 @@ States: hover (`bg-secondary-hover`), focus (3px `ring-ring/50`), active (`opaci
215
225
  <Badge variant="default-success" /> // Green
216
226
  <Badge variant="default-fail" /> // Red
217
227
 
228
+ // Standard (neutral grey chip) — for non-status meta like contract type, duration
229
+ <Badge variant="standard" />
230
+
218
231
  // Fill (tint background)
219
232
  <Badge variant="fill" /> // Blue tint
220
233
  <Badge variant="fill-success" /> // Green tint
@@ -595,7 +608,15 @@ Design tokens are managed in Figma and exported as CSS variables. To update:
595
608
 
596
609
  ## Changelog
597
610
 
598
- ### Unreleased
611
+ ### v0.14.0
612
+ - **New Result block:** Fixed-width (320 px) end-of-round result card with 5 variants — Win/continuing, Loss/continuing, End of demo, Out of balance, On a roll. Thumb-up/down SVG with subtle radial halo + idle motion (float for win, head-shake for loss). Title (`You won!` / `You lost!`), amount headline in semantic colour, contract + duration `standard` Badge pills, and CTA(s). Digit contracts render the picked digit inside the contract pill with a thin vertical divider. Out-of-balance and on-a-roll variants are dialog-only (no thumb / no amount) — title + body + 2 CTAs. Lives under **Blocks → Result** in the playground.
613
+ - **Sheet Open Positions redesign:** Each row now uses a 2-col layout — bet name + stake (left) / PnL + market·duration (right). Dropped per-row asset (`V100`), round number, and digit/multiplier suffix labels (the game is already implied by the sheet/tab title). Abbreviated durations (sec / min / hr / day) and dropped the `Stake ` prefix on amounts. Added an "Edge cases" row demonstrating drawer behavior with 1 item and 30 items.
614
+ - **Section nav sheet — desktop-safe:** The mobile section picker `Sheet` is now conditionally mounted (`{isMobile && …}`) so it can't be triggered at desktop widths where the permanent sidebar is already visible, avoiding redundant overlay layers.
615
+ - **Badge — new `standard` variant:** Neutral grey chip (`bg-subtle` / `text-on-prominent`) for non-status meta like contract type and duration. Existing `default` (solid blue) and all other variants are unchanged.
616
+ - **TicketCard / BoostTicketCard:**
617
+ - Left content restructured as a 2-column grid so the icon circle scales to match the **label + value height** (was a fixed `size-10` centered against the entire column).
618
+ - Boost badge now sits in row 2 of column 2 — aligned under the value, not pinned to the card's left edge.
619
+ - **2-decimal balance formatting:** the `value` prop is now normalised by `formatBalanceValue` before render, so values always display with exactly two decimal places regardless of input (e.g. `$12,450` → `$12,450.00`, `$12,450.5` → `$12,450.50`, `1234` → `1,234.00`). Currency prefix/suffix is preserved.
599
620
  - **Token convention — `on-<surface>` foreground pairs:** Added a Material-style paired foreground for every semantic surface so colour roles are self-documenting and resolve robustly across consumer setups (incl. Module Federation, where raw `var()` fallbacks were previously needed). New CSS variables and Tailwind utilities:
600
621
  - `--on-primary` (white) / `text-on-primary` — paired with `bg-primary`
601
622
  - `--primary-inverse` (white) / `bg-primary-inverse` — inverted primary surface for use on dark/coloured areas