@trading-game/design-intelligence-layer 1.0.7 → 1.2.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.
@@ -1,366 +0,0 @@
1
- ---
2
- description: Enforce correct usage of the @trading-game/design-intelligence-layer npm package. Apply whenever building UI in a project that has the package installed — before writing any component, layout, or styled element.
3
- globs: ["**/*.tsx", "**/*.jsx", "**/*.ts", "**/*.css"]
4
- alwaysApply: true
5
- ---
6
-
7
- # @trading-game/design-intelligence-layer — AI Agent Usage Rules
8
-
9
- ## Rule 1 — Check the package before writing any custom UI
10
-
11
- **BEFORE** writing any `<div>`, `<button>`, `<span>`, or other element styled with Tailwind classes, you MUST check if a component already exists in `@trading-game/design-intelligence-layer`.
12
-
13
- ### Available components (check this list first)
14
-
15
- Accordion, Alert, AlertDialog, AspectRatio, Avatar, AvatarGroup, Badge, **Banner**, Breadcrumb, Button, Calendar, Card, Carousel, Chart, Checkbox, **Chip**, Collapsible, Combobox, Command, ContextMenu, Dialog, Direction, Drawer, DropdownMenu, Empty, Field, Form, HoverCard, Input, InputGroup, InputOTP, Item, Kbd, Label, **Link**, Menubar, NativeSelect, NavigationButton, NavigationMenu, Pagination, Popover, Progress, RadioGroup, Resizable, ScrollArea, Select, Separator, Sheet, Sidebar, Skeleton, Slider, Spinner, **Stepper**, Switch, Table, Tabs, Textarea, **TicketCard / CreditTicketCard**, Toast/Toaster, **ResultSnackbar**, Toggle, ToggleGroup, Tooltip
16
-
17
- ### Decision flow
18
-
19
- ```
20
- Does a component exist in the list above?
21
- YES → Import it from @trading-game/design-intelligence-layer. Do NOT re-implement it.
22
- NO → STOP. Tell the user:
23
- "The [ComponentName] component does not exist in @trading-game/design-intelligence-layer.
24
- Options:
25
- (a) Build a custom one using design system tokens only
26
- (b) Use a different existing component
27
- (c) Skip this component"
28
- Wait for user to choose. Do NOT proceed without confirmation.
29
- ```
30
-
31
- ### Correct import pattern
32
-
33
- ```tsx
34
- import { Button, Card, Badge } from "@trading-game/design-intelligence-layer"
35
- ```
36
-
37
- ---
38
-
39
- ## Rule 2 — Token-only rule (applies to ALL code, including approved custom builds)
40
-
41
- ### Never use
42
-
43
- ```
44
- ❌ Hardcoded hex: #2323FF, #000000, rgba(0,0,0,0.5)
45
- ❌ Raw Tailwind palette: bg-gray-100, text-zinc-500, text-slate-400, bg-black, bg-white
46
- ❌ Arbitrary color: bg-[#EEEEEE], text-[rgba(35,35,255,0.1)]
47
- ❌ Raw CSS var: bg-[var(--border-subtle)] ← NEVER do this
48
- ❌ hsl(var()) syntax: hsl(var(--primary)) ← this is Tailwind v3, not v4
49
- ❌ Raw opacity on non-tokens: bg-black/50
50
- ```
51
-
52
- ### Always use semantic token classes
53
-
54
- #### Background tokens
55
- ```
56
- ✅ bg-prominent — page background (white #FFFFFF)
57
- ✅ bg-card — card/panel surface (white #FFFFFF)
58
- ✅ bg-popover — popover/dropdown surface (white #FFFFFF)
59
- ✅ bg-subtle — subtle tinted surface (#F5F5F5)
60
- ✅ bg-overlay — modal/dialog backdrop (black 50%) — ONLY for overlays
61
- ✅ bg-primary — brand blue #2323FF — CTAs and primary actions
62
- ✅ bg-primary-hover — darker blue #0B0BD2 — primary button hover
63
- ✅ bg-primary-inverse — white surface for use on dark/coloured areas
64
- ✅ bg-prominent-inverse — dark surface for use on light pages (toasts, etc.)
65
- ✅ bg-secondary-hover — light grey #EEEEEE — outline/secondary button hover
66
- ✅ bg-semantic-win — green — profit/positive
67
- ✅ bg-semantic-loss — red — loss/negative
68
- ✅ bg-semantic-warning — orange — warning/caution
69
- ✅ bg-semantic-boost — amber-orange #F9840F — boost/bonus badge (tinted: bg-semantic-boost/16)
70
- ```
71
-
72
- #### Text tokens — paired with a surface
73
-
74
- > Convention: `bg-<surface>` always has a paired `text-on-<surface>` foreground. Use them together for guaranteed legibility.
75
-
76
- ```
77
- ✅ text-on-prominent — paired with bg-prominent (black #000000) — default body text
78
- ✅ text-on-prominent-inverse — paired with bg-prominent-inverse (white) — toast text, etc.
79
- ✅ text-on-primary — paired with bg-primary (white) — primary button label, tooltip text
80
- ✅ text-on-primary-inverse — paired with bg-primary-inverse (blue) — primary-inverse button label
81
- ✅ text-on-semantic-win — paired with bg-semantic-win (white)
82
- ✅ text-on-semantic-loss — paired with bg-semantic-loss (white)
83
- ✅ text-on-semantic-warning — paired with bg-semantic-warning (white)
84
- ✅ text-on-semantic-boost — paired with bg-semantic-boost (dark amber #713813)
85
- ✅ text-on-subtle — secondary text (aliases text-subtle-default: mono-800 #717171 light / mono-600 #AAAAAA dark)
86
- ✅ text-on-disabled — disabled / inactive text (aliases text-disabled-default: mono-400 #C6C6C6 light / mono-900 #555555 dark)
87
-
88
- ✅ text-primary — brand blue #2323FF — inline brand text over neutral surfaces
89
- ✅ text-semantic-win — green — profit/positive inline text
90
- ✅ text-semantic-loss — red — loss/negative inline text
91
- ```
92
-
93
- > ⚠️ **Deprecated:** `text-on-prominent-static-inverse` still works (aliased to `--on-prominent-inverse`) but new code should pick the explicit `text-on-<surface>` for whatever background sits behind the text.
94
-
95
- #### Border tokens
96
- ```
97
- ✅ border-border-subtle — light grey #EEEEEE — default UI borders, dividers, cards
98
- ✅ border-border-prominent — pure black #000000 — outline variant components
99
- ✅ border-border — @deprecated alias for border-subtle (still works, prefer border-border-subtle)
100
- ✅ border-input — input field borders (same value as border-subtle)
101
- ✅ ring-ring — focus ring (blue #2323FF)
102
- ```
103
-
104
- #### Opacity on a token is fine
105
- ```
106
- ✅ bg-primary/20, border-border-subtle/50, ring-ring/10
107
- ```
108
-
109
- ---
110
-
111
- ## Rule 3 — Layout utilities are exempt
112
-
113
- Structural Tailwind utilities are freely usable without token rules:
114
-
115
- ```
116
- ✅ flex, grid, gap-4, p-6, m-2, w-full, h-screen, max-w-lg
117
- ✅ z-50, overflow-hidden, opacity-50, transition-all
118
- ✅ col-span-2, items-center, justify-between
119
- ```
120
-
121
- Token rules apply **only** to: color (bg, text, border, ring, shadow color), border radius, and font family.
122
-
123
- ---
124
-
125
- ## Rule 3.5 — Typography: use the type scale, never hand-written sizes
126
-
127
- **MANDATORY decision procedure for ANY text you render.** Do not choose font sizes. Every piece of text gets its size, line-height, and weight from one of the 13 scale classes below — this is what keeps every screen's hierarchy identical.
128
-
129
- ### Step 1 — Is there a component for it?
130
-
131
- If the text lives in a component slot, USE THE COMPONENT — every component carries its own typography internally (via private component tokens or a built-in scale class):
132
- `DialogTitle` / `AlertDialogTitle` / `SheetTitle` / `DrawerTitle` / `EmptyTitle`, `CardTitle`, every `*Description` slot, `Label` / `FieldLabel` / `FieldTitle` / `ItemTitle`, `AccordionTrigger` / `AccordionContent`, `Button` — never hand-style any component's text.
133
-
134
- ### Step 2 — Freeform text: pick from the scale
135
-
136
- | Class | Size / line | Weight | Use for |
137
- | ------------ | ----------- | ------------- | ------------------------------------------------------ |
138
- | `display` | 36→56 fluid | ExtraBold 800 | Hero statement on a landing/marketing page |
139
- | `h1` | 30→40 fluid | Bold 700 | The single main title of a page/screen (ONE per page) |
140
- | `h2` | 26→32 fluid | Bold 700 | A major section heading |
141
- | `h3` | 22→24 fluid | SemiBold 600 | A sub-group heading inside a section |
142
- | `h4` | 20 / 28 | SemiBold 600 | A dashboard panel / large feature-card header |
143
- | `h5` | 18 / 24 | SemiBold 600 | Dialog, sheet, and drawer titles (freeform) |
144
- | `h6` | 16 / 24 | SemiBold 600 | A card / compact panel title (freeform) |
145
- | `body-lg` | 18 / 28 | Regular 400 | Intro / lead paragraph |
146
- | `body-md` | 16 / 24 | Regular 400 | Default body text |
147
- | `body-sm` | 14 / 20 | Regular 400 | Description under a title, helper copy |
148
- | `label-text` | 14 / 20 | Medium 500 | Form label, list-item title, table header (freeform) |
149
- | `caption` | 12 / 16 | Medium 500 | Metadata, timestamps, fine print |
150
- | `overline` | 12 / 16 | SemiBold 600 | Eyebrow above a heading, tag (uppercases itself) |
151
-
152
- **`h1`–`h6` are STYLE names, not HTML tags.** Put the class on whatever element the document outline needs — `<h2 className="h4">` is correct and normal when heading level and visual size legitimately differ. Never let the class name pick the tag for you.
153
-
154
- ```tsx
155
- ✅ <h1 className="h1 text-on-prominent">Account settings</h1>
156
- ✅ <h2 className="h2 text-on-prominent">Security</h2>
157
- ✅ <p className="body-sm text-on-subtle">Manage your sign-in methods.</p>
158
- ✅ <span className="overline text-primary">New</span> {/* uppercases itself */}
159
- ```
160
-
161
- ### Hard rules
162
- ```
163
- ❌ NEVER hand-build titles/body from utilities (text-2xl font-bold tracking-tight, text-[13px]…)
164
- ❌ NEVER uppercase a heading — the system is sentence-case; only `overline` uppercases (automatically)
165
- ❌ NEVER add responsive size overrides (md:text-*, sm:text-*) to a scale class — display and
166
- h1–h3 already scale desktop→mobile via their tokens. A class NEVER changes between
167
- breakpoints: h2 on desktop is h2 on mobile.
168
- ❌ NEVER use more than one h1 per page; never skip more than one hierarchy level
169
- ❌ NEVER tweak a scale class with utilities (h5 font-medium does nothing — scale classes are
170
- unlayered CSS and beat utilities). Need something different? Use a different class.
171
- ✅ Emphasis inside body text: <b>/<span> + font-semibold on that span — never a bigger size
172
- ✅ Numeric data displays (P&L, balances) are the accepted exception: bespoke size + tabular-nums
173
- ✅ A SMALLER class passed via className overrides a component's built-in one (stylesheet is
174
- ordered largest→smallest), e.g. <EmptyTitle className="h6"> for compact contexts
175
- ```
176
-
177
- > Naming notes: `overline` is also a Tailwind text-decoration utility — the package's class wins and clears the line. The label class is `label-text` (not `label`) to avoid confusion with the `Label` component.
178
-
179
- ---
180
-
181
- ## Rule 3.6 — Result Snackbar is for a settled game result, and nothing else
182
-
183
- `ResultSnackbar` exists for exactly one thing: reporting a **settled contract the player was not watching** — a win or a loss, with its figure.
184
-
185
- ```
186
- Did a contract just settle, win or loss, off-screen?
187
- YES → ResultSnackbar
188
- NO → toast(...) // everything else
189
- ```
190
-
191
- Use `toast(...)` — never `ResultSnackbar` — for:
192
-
193
- - **Refunds.** Nothing was won or lost, so there is no figure to report. A refund is a non-event.
194
- - **Trade rejections, live payout warnings, connection problems**, and every other notification.
195
- - Anything that needs an **action** from the player. `ResultSnackbar` is pointer-transparent by design: it is a report, not a control.
196
-
197
- And do not use it for the contract the player **was** watching as it ended — that gets the full-screen result moment. `ResultSnackbar` deliberately does not take the board.
198
-
199
- It is never the surface of record either. Every result also lands in positions and history, which is where a player goes to study terms.
200
-
201
- **Why the two look nothing alike:** that difference is intentional, not drift. `toast` is transient system messaging on the inverse surface. `ResultSnackbar` reports money: floating-chrome glass, an illustration, a signed figure in outcome ink, and a visible dwell timer. Do not "unify" them.
202
-
203
- ```tsx
204
- import { ResultSnackbar } from "@trading-game/design-intelligence-layer"
205
-
206
- <ResultSnackbar
207
- outcome="win" // "win" | "loss" — the only two states
208
- amount="+8.40" // pre-signed; use a true Unicode minus for losses
209
- amountValue={8.4} // optional count-up target
210
- currency="USDT"
211
- contractLabel="Rise"
212
- duration="15 seconds"
213
- icon={<img src="/thumbs-up.webp" alt="" aria-hidden className="size-8" />}
214
- onDismiss={advanceQueue} // fires once, after the exit finishes
215
- className="absolute top-3 right-3" // placement is yours; anchor it to something meaningful
216
- />
217
- ```
218
-
219
- Placement and queueing are the consumer's: the meaningful anchor differs per game, and deciding what waits, what is stale, and what replays after an interruption is product logic. The component shows one settlement and reports when it is done.
220
-
221
- ---
222
-
223
- ## Rule 4 — Do NOT install or configure these separately
224
-
225
- ```
226
- ❌ Do NOT install lucide-react — it is already bundled in the package
227
- ❌ Do NOT install tailwindcss separately — the package ships its own Tailwind v4 setup
228
- ❌ Do NOT add a tailwind.config.js — configuration is handled by the package
229
- ❌ Do NOT use @apply with hsl(var(--token)) — Tailwind v4 uses CSS variables directly
230
- ❌ Do NOT override font-family manually in CSS — use font-display and font-body utility classes
231
- ```
232
-
233
- ### Correct CSS setup in the consuming project
234
-
235
- ```css
236
- @import "@trading-game/design-intelligence-layer/styles";
237
- @import "tailwindcss";
238
- @source "../node_modules/@trading-game/design-intelligence-layer/dist";
239
- ```
240
-
241
- ### Vite projects — required plugin
242
-
243
- If the project uses Vite, `@tailwindcss/vite` MUST be in `vite.config.js`:
244
-
245
- ```js
246
- import tailwindcss from '@tailwindcss/vite'
247
- // plugins: [react(), tailwindcss()]
248
- ```
249
-
250
- Without this, Tailwind CSS will not process any styles. Next.js projects do NOT need this.
251
-
252
- ---
253
-
254
- ## Rule 5 — Button and Badge variants
255
-
256
- ### Button variants
257
- ```tsx
258
- // Light surfaces
259
- <Button variant="primary" /> // Blue filled — main CTA
260
- <Button variant="secondary" /> // Black outline — secondary actions
261
- <Button variant="tertiary" /> // Text only — minimal
262
-
263
- // Dark / coloured surfaces
264
- <Button variant="primary-inverse" /> // White filled + blue text — main CTA on dark bg
265
- <Button variant="secondary-inverse" /> // White outline + white text — secondary on dark bg
266
- ```
267
-
268
- All variants support icon sizes — use `size="icon-lg|icon-md|icon-sm|icon-xs"` for icon-only buttons on any variant:
269
- ```tsx
270
- <Button variant="primary-inverse" size="icon-md"><Bell /></Button>
271
- <Button variant="secondary-inverse" size="icon-sm"><X /></Button>
272
- ```
273
-
274
- ### Badge variants
275
- ```tsx
276
- // Solid
277
- <Badge variant="default" /> // Blue solid
278
- <Badge variant="standard" /> // Subtle grey solid
279
- <Badge variant="default-success" /> // Green solid
280
- <Badge variant="default-fail" /> // Red solid
281
- <Badge variant="default-warning" /> // Orange solid
282
-
283
- // Tint
284
- <Badge variant="fill" /> // Blue tint bg
285
- <Badge variant="fill-success" /> // Green tint bg
286
- <Badge variant="fill-fail" /> // Red tint bg
287
- <Badge variant="fill-warning" /> // Orange tint bg
288
- <Badge variant="fill-credit" /> // Deep peach (#FDCA8A) + bold amber text — credit/boost (Welcome credit, bonus)
289
- <Badge variant="fill-demo" /> // Peach + red-orange text — demo / test-mode indicator
290
-
291
- // Outline (black border, hover grey)
292
- <Badge variant="outline" />
293
-
294
- // Ghost (transparent bg)
295
- <Badge variant="ghost" />
296
- <Badge variant="ghost-success" />
297
- <Badge variant="ghost-fail" />
298
- <Badge variant="ghost-warning" />
299
- ```
300
-
301
- ---
302
-
303
- ## Rule 6 — If in doubt, stop and ask
304
-
305
- If you cannot find a token for a value you need, do NOT fall back to a hardcoded value.
306
-
307
- Stop and tell the user:
308
- ```
309
- "I need [value] for [element]. No design token exists for this.
310
- Should I: (a) use a hardcoded value, or (b) skip this styling?"
311
- ```
312
-
313
- Wait for confirmation before proceeding.
314
-
315
- ---
316
-
317
- ## Rule 8 — Blocks are first-class exports (import them by name)
318
-
319
- **Blocks** are opinionated, composed UI sections — exported from `@trading-game/design-intelligence-layer` the same as primitives. Import by name and pass data via props. Variants live as a `layout` / `mode` / `status` prop on a single block, not as separate components.
320
-
321
- ```
322
- ✅ Import blocks directly from the package — same pattern as primitives
323
- ✅ Pass data via props; variants are configured via a single variant prop
324
- ✅ Block names ARE valid component names (treat them like Rule 1 components)
325
- ❌ Do NOT re-implement a block by hand if a block export already covers it
326
- ❌ Do NOT split variants into separate blocks — use the variant prop
327
- ```
328
-
329
- | Block | Variants | Importable? |
330
- |-------|----------|-------------|
331
- | `HeroBlock` | `layout: "centered" \| "split"` | Yes — `import { HeroBlock }` |
332
- | `AuthBlock` | `mode: "sign-in" \| "sign-up"` | Yes — `import { AuthBlock }` |
333
- | `FAQBlock` | `layout: "desktop" \| "mobile"` | Yes — `import { FAQBlock }` |
334
- | `NavBarBlock` | — (internal mobile-menu state) | Yes — `import { NavBarBlock }` |
335
- | `HeaderNavigationBlock` | — (optional `history.count` badge) | Yes — `import { HeaderNavigationBlock }` |
336
- | `OpenPositionsBlock` | `Position` discriminated union | Yes — `import { OpenPositionsBlock, type Position }` |
337
- | `ResultBlock` | `status` + `ctaMode` | Yes — `import { ResultBlock }` |
338
- | `ResultDialog` | — | Yes — `import { ResultDialog }` |
339
-
340
- See `guides/design-system-guide/trading-game-ds-guide.md` § 8.5 for full per-block API, used components, and used tokens.
341
-
342
- ---
343
-
344
- ## Rule 7 — Package version upgrades (stay aligned with the published design system)
345
-
346
- When the user asks to **update**, **upgrade**, or **install the latest** `@trading-game/design-intelligence-layer`, or after the dependency version changes in `package.json`:
347
-
348
- ### How updates actually apply
349
-
350
- - If the project **imports components only** from `@trading-game/design-intelligence-layer`, new styles and behavior come from **`node_modules/.../dist`** after **`npm install` / `npm ci` and a dev or production build**. The package is the source of truth — no AI step is required for those imports to change.
351
- - If the repo **contains copied or forked** files that mirror package components (e.g. a local `components/ui/button.tsx` with full implementation), **`npm install` does not update those files.** They stay stale until someone reconciles them.
352
-
353
- ### What you MUST do after a design-system version bump
354
-
355
- 1. **Search for local duplication** — Look for UI files that re-implement package exports (`components/ui/`, `@/components/ui`, etc.). Flag any file that is not a **thin re-export** or **documented wrapper** around the package.
356
- 2. **Reconcile** — Prefer **removing** duplicate implementations and **importing from the package**. If a fork must stay, align it with the **exact** current implementation in the installed package (or tag on GitHub) and document why it diverges (file name + reason).
357
- 3. **Notify on replace** — If you **delete, replace, or substantially overwrite** local component code to match the package, **stop and tell the user clearly**, e.g.
358
- `Aligned [ComponentName] with @trading-game/design-intelligence-layer@[version]. Previous local behavior or classes: [short summary]. Re-apply needs via package variants/props, tokens, or a thin wrapper only if product requires it.`
359
- 4. **Review `className` overrides** — Parent apps often pass `className` on DS components. Old overrides (radius, colors, shadows) can **hide** new defaults (e.g. pill buttons). After upgrade, scan for overrides on DS components and trim or adjust them when they conflict with the new design.
360
- 5. **Refresh Cursor rules** — The package ships `guides/rules/design-system-consuming-project.mdc`. Cursor does **not** read it from `node_modules` automatically. Tell the user to re-copy it (see README **AI Agent Setup → Cursor**) so agent instructions match the release.
361
- 6. **Tailwind** — Confirm `@source` still points at `node_modules/@trading-game/design-intelligence-layer/dist` so Tailwind v4 emits classes from the updated bundle.
362
-
363
- ### Do not assume
364
-
365
- - Do **not** assume `npm update` alone fixed forked files in the app repo.
366
- - Do **not** silently delete user customizations — always report what was removed or replaced and offer a token-safe way to re-apply if needed.