@deriv-ds/design-intelligence-layer 0.1.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.
@@ -0,0 +1,682 @@
1
+ # Trading Game Design System Guide
2
+
3
+ > **Package:** `@trading-game/design-intelligence-layer`
4
+ > **Audience:** AI agents and developers building UI for the Trading Game. This is the single source of truth for setting up and using the design system in any project.
5
+
6
+ ---
7
+
8
+ ## MANDATORY RULES — READ FIRST
9
+
10
+ ### Rule 1 — Component existence check
11
+
12
+ ```
13
+ BEFORE using any component:
14
+ 1. Check the Component Catalogue (Section 8). Does it exist?
15
+ YES → Import it from the npm package exactly as documented. Do NOT re-implement it.
16
+ NO → STOP. Tell the user:
17
+ "The [ComponentName] component does not exist in the Trading Game design system.
18
+ Options:
19
+ (a) Build a custom one using design system tokens only (no hardcoded colors or values)
20
+ (b) Use a different component that exists in the system
21
+ (c) Skip this component entirely"
22
+ Wait for the user to choose. Do NOT proceed without confirmation.
23
+ ```
24
+
25
+ ### Rule 2 — Token-only styling
26
+
27
+ ```
28
+ NEVER use:
29
+ ❌ Hardcoded hex: #2323FF, #FFFFFF, etc.
30
+ ❌ Raw Tailwind palette: bg-gray-100, text-zinc-500, text-slate-400, bg-black, bg-white
31
+ ❌ Raw opacity on non-tokens: bg-black/50 (use bg-overlay instead)
32
+ ❌ Arbitrary color values: bg-[#FF6600], text-[rgba(0,0,0,0.5)]
33
+ ❌ hsl(var(--token)) syntax — this is Tailwind v3. This project uses Tailwind v4.
34
+ ❌ Non-existent tokens: bg-hover, bg-badge-rank, text-primary-foreground, text-on-decorative
35
+ ❌ border-border — deprecated alias; use border-border-subtle or border-border-prominent
36
+
37
+ ALWAYS use semantic tokens:
38
+ ✅ bg-prominent, bg-card, bg-popover, bg-subtle, bg-overlay
39
+ ✅ text-on-prominent, text-on-subtle
40
+ ✅ border-border-subtle, border-border-prominent, ring-ring
41
+ ✅ bg-primary, bg-primary-hover, bg-secondary-hover
42
+ ✅ text-semantic-win, text-semantic-loss, text-semantic-warning
43
+ ✅ Opacity on a token IS allowed: bg-primary/20, border-border-subtle/50, ring-primary/10
44
+ ```
45
+
46
+ ### Rule 3 — Layout utilities are exempt
47
+
48
+ ```
49
+ Tailwind layout/spacing utilities are freely usable for structural layout:
50
+ ✅ flex, grid, gap-4, p-6, m-2, w-full, h-screen, max-w-lg, col-span-2, etc.
51
+ ✅ z-50, overflow-hidden, transition-all, etc.
52
+
53
+ Token rules apply ONLY to:
54
+ - Color (background, text, border, ring, shadow color)
55
+ - Border radius (use the design system's radius scale — see Section 5)
56
+ - Typography (font family must use font-display or font-body, never raw font names)
57
+ ```
58
+
59
+ ### Rule 4 — Do NOT install or import these separately
60
+
61
+ ```
62
+ ❌ lucide-react — already bundled in the npm package
63
+ ❌ tailwindcss — the package ships its own Tailwind v4 config
64
+ ❌ @apply with hsl(var(--token)) — Tailwind v4 uses CSS variables directly
65
+ ❌ tailwind.config.js — configuration is handled by the package via CSS
66
+ ❌ Manual font-family in CSS — use font-display and font-body utility classes
67
+ ```
68
+
69
+ ### Rule 5 — Complexity-aware implementation
70
+
71
+ ```
72
+ Each component in the catalogue is tagged:
73
+ [simple] → Drop in, one import, works immediately
74
+ [composed] → Has required sub-components; use the full pattern shown
75
+ [complex] → Has significant state or setup; ask clarifying questions first
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 1 — Quick Start
81
+
82
+ ### Step 1 — Install the package
83
+
84
+ ```bash
85
+ npm install @trading-game/design-intelligence-layer@latest --safe-chain-skip-minimum-package-age
86
+ ```
87
+
88
+ ### Step 2 — Add CSS imports
89
+
90
+ In your main CSS file (e.g. `globals.css` or `index.css`):
91
+
92
+ ```css
93
+ @import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap");
94
+ @import "tailwindcss";
95
+ @import "@trading-game/design-intelligence-layer/styles";
96
+ @source "../node_modules/@trading-game/design-intelligence-layer/dist";
97
+ ```
98
+
99
+ > **Note:** Fonts are loaded via a direct Google Fonts `@import` URL. Do NOT use `next/font`.
100
+
101
+ ### Step 3 — Set base HTML class
102
+
103
+ The design system is light-first. No extra class is required on `<html>` for the default light theme. A `.dark` class is reserved for future dark theme support but not yet styled.
104
+
105
+ ### Step 4 — Import components
106
+
107
+ ```tsx
108
+ import { Button, Card, Badge } from "@trading-game/design-intelligence-layer"
109
+ ```
110
+
111
+ ---
112
+
113
+ ## 2 — Design Tokens
114
+
115
+ > This is the single authoritative token reference. All tokens are defined as CSS variables in the package and mapped to Tailwind utility classes automatically.
116
+
117
+ ### 2.1 — Backgrounds
118
+
119
+ | CSS Variable | Tailwind Class | Usage |
120
+ | ---------------- | ---------------- | ------------------------- |
121
+ | `--prominent` | `bg-prominent` | Main page background |
122
+ | `--card` | `bg-card` | Cards, panels, modals |
123
+ | `--popover` | `bg-popover` | Popovers, elevated cards |
124
+ | `--subtle` | `bg-subtle` | Muted / secondary surfaces|
125
+ | `--overlay` | `bg-overlay` | Modal/dialog/drawer/sheet backdrop (semi-transparent) |
126
+ | `--tabs` | `bg-tabs` | Tab container / tab bar background (`variant="default"`) — 4% black alpha, adapts to any surface |
127
+ | `--tabs-active` | `bg-tabs-active` | Active / selected tab background — solid white |
128
+
129
+ ### 2.2 — Primary (Brand Blue)
130
+
131
+ | CSS Variable | Tailwind Class | Usage |
132
+ | --------------------- | ------------------- | ------------------------- |
133
+ | `--primary` | `bg-primary` / `text-primary` | Primary CTA, brand color, interactive elements |
134
+ | `--primary-hover` | `bg-primary-hover` | Hover & pressed states on primary elements |
135
+
136
+ ### 2.3 — Semantic (Trading Status)
137
+
138
+ | CSS Variable | Tailwind Class | Usage |
139
+ | -------------------- | ----------------------- | ------------------------- |
140
+ | `--semantic-win` | `text-semantic-win` / `bg-semantic-win` | Win / Profit / Positive outcomes |
141
+ | `--semantic-loss` | `text-semantic-loss` / `bg-semantic-loss` | Loss / Negative outcomes |
142
+ | `--semantic-warning` | `text-semantic-warning` / `bg-semantic-warning` | Warning / Caution / Non-destructive alerts |
143
+ | `--semantic-info` | `text-semantic-info` / `bg-semantic-info` | Informational alerts |
144
+
145
+ > All semantic tokens support opacity variants (e.g. `bg-semantic-warning/10` for tinted backgrounds). For structured alpha surfaces, use the primitive alpha scales — see Section 2.10.
146
+
147
+ ### 2.4 — Text & Icon Colors
148
+
149
+ | CSS Variable | Tailwind Class | Usage |
150
+ | ------------------------------- | --------------------------------------- | ------------------------- |
151
+ | `--on-prominent` | `text-on-prominent` | Primary text (headings, body) |
152
+ | `--on-prominent-static-inverse` | `text-on-prominent-static-inverse` | Always-white text (e.g. on primary blue buttons) |
153
+ | `--on-subtle` | `text-on-subtle` | Secondary text (descriptions, labels) |
154
+
155
+ ### 2.5 — Borders & Inputs
156
+
157
+ | CSS Variable | Tailwind Class | Usage |
158
+ | ------------------- | ------------------------- | ------------------------- |
159
+ | `--border-subtle` | `border-border-subtle` | Default light border |
160
+ | `--border-prominent`| `border-border-prominent` | Strong / emphasized border|
161
+ | `--input` | `border-input` | Input resting state border|
162
+ | `--ring` | `ring-ring` / `border-ring` | Focus ring and focus border color |
163
+
164
+ ### 2.6 — Supporting Colors
165
+
166
+ | CSS Variable | Tailwind Class | Usage |
167
+ | ------------------------ | -------------------- | ------------------------- |
168
+ | `--secondary-hover` | `bg-secondary-hover` | Hover bg on neutral elements (light gray) |
169
+ | `--slider-range` | `bg-slider-range` | Slider range fill (primary at 40%) |
170
+ | `--alert-info-text` | `text-alert-info-text` | Alert info text color |
171
+ | `--alert-info-border` | `border-alert-info-border` | Alert info border |
172
+ | `--alert-error-text` | `text-alert-error-text` | Alert error text color |
173
+ | `--alert-error-border` | `border-alert-error-border` | Alert error border |
174
+
175
+ > **Accent (orange) and Violet:** `--primitive-orange-500` and `--primitive-violet-500` are available as CSS variables only (no Tailwind utility class). Use `var(--primitive-orange-500)` directly for rank badges and special highlights.
176
+
177
+ ### 2.7 — Opacity Patterns
178
+
179
+ | Usage | Tailwind Class |
180
+ | ------------------------------ | ---------------------- |
181
+ | Subtle hover tint | `bg-primary/[0.08]` |
182
+ | Medium highlight | `bg-primary/[0.16]` |
183
+ | Selected/active tint | `bg-primary/10` |
184
+ | Status badge tint backgrounds | `bg-semantic-win/10`, `bg-semantic-loss/10`, etc. |
185
+
186
+ ### 2.8 — Interactive States
187
+
188
+ > **`bg-hover` does not exist.** Use `bg-secondary-hover` or `bg-primary/[0.08]` for hover states.
189
+
190
+ **Universal pattern for interactive list/row/chip elements** (except Button and Tabs which have their own):
191
+
192
+ | State | Background | Text |
193
+ | -------- | -------------------- | ---------------------------------- |
194
+ | Default | transparent | `text-on-prominent` or `text-on-subtle` |
195
+ | Hover | `bg-secondary-hover` | `text-primary` |
196
+ | Selected | `bg-secondary-hover` | `text-primary font-semibold` |
197
+
198
+ > **NEVER** use `bg-accent` or `text-accent-foreground`. Do NOT add borders to selected states.
199
+
200
+ ### 2.9 — Transitions
201
+
202
+ **Duration tokens:**
203
+
204
+ | Tailwind Class | CSS Variable | Value | Usage |
205
+ | ----------------- | ------------------------------ | ------ | -------------------------------------- |
206
+ | `duration-instant`| `--primitive-duration-instant` | `50ms` | Focus rings, hover color tints |
207
+ | `duration-fast` | `--primitive-duration-fast` | `100ms`| Buttons, inputs, badges, checkboxes |
208
+ | `duration-base` | `--primitive-duration-base` | `200ms`| Dropdowns, popovers, accordions |
209
+ | `duration-slow` | `--primitive-duration-slow` | `300ms`| Dialogs, sheets, drawers closing |
210
+ | `duration-open` | `--primitive-duration-open` | `500ms`| Sheets, drawers entering |
211
+
212
+ **Easing tokens:**
213
+
214
+ | Tailwind Class | CSS Variable | Value | Usage |
215
+ | ---------------- | ----------------------------- | ------------------------------ | -------------------------------------- |
216
+ | `ease-standard` | `--primitive-ease-standard` | `cubic-bezier(0.2, 0, 0, 1)` | General UI — bidirectional state changes |
217
+ | `ease-enter` | `--primitive-ease-enter` | `cubic-bezier(0, 0, 0.2, 1)` | Overlays / surfaces entering |
218
+ | `ease-exit` | `--primitive-ease-exit` | `cubic-bezier(0.4, 0, 1, 1)` | Overlays / surfaces leaving |
219
+ | `ease-linear` | `--primitive-ease-linear` | `linear` | Sidebar width, progress bar |
220
+
221
+ **Usage pattern:**
222
+
223
+ ```tsx
224
+ <div className="transition-colors duration-fast ease-standard">...</div>
225
+ ```
226
+
227
+ ### 2.10 — Primitive Alpha Scales
228
+
229
+ > Raw alpha (opacity) variants of the mono and blue primitives. These are **internal CSS variables only** — not exposed as Tailwind utility classes. Reference them only from semantic tokens, never directly in components.
230
+
231
+ **Naming convention:** `--primitive-[color]-alpha-[stop]`
232
+
233
+ **Mono alpha scale** (black — `oklch(0 0 0 / X%)`)
234
+
235
+ | CSS Variable | Opacity | Typical use |
236
+ | ----------------------------- | ------- | ---------------------------------------- |
237
+ | `--primitive-mono-alpha-4` | 4% | Tab container background (`--tabs`) |
238
+ | `--primitive-mono-alpha-8` | 8% | Subtle hover tint |
239
+ | `--primitive-mono-alpha-16` | 16% | Pressed / active surface tint |
240
+ | `--primitive-mono-alpha-24` | 24% | Medium-weight tinted surface |
241
+ | `--primitive-mono-alpha-32` | 32% | Disabled state overlay |
242
+ | `--primitive-mono-alpha-40` | 40% | Strong tint / scrim |
243
+ | `--primitive-mono-alpha-50` | 50% | Backdrop overlay (replaces `--primitive-black-50`) |
244
+ | `--primitive-mono-alpha-64` | 64% | Heavy overlay |
245
+ | `--primitive-mono-alpha-80` | 80% | Near-opaque overlay |
246
+
247
+ **Blue alpha scale** (brand blue — `oklch(0.476 0.297 267.4 / X%)`)
248
+
249
+ | CSS Variable | Opacity | Typical use |
250
+ | ----------------------------- | ------- | ---------------------------------------- |
251
+ | `--primitive-blue-alpha-4` | 4% | Extremely subtle brand tint |
252
+ | `--primitive-blue-alpha-8` | 8% | Hover tint on brand surfaces |
253
+ | `--primitive-blue-alpha-16` | 16% | Selected / active brand tint |
254
+ | `--primitive-blue-alpha-24` | 24% | Medium brand surface highlight |
255
+ | `--primitive-blue-alpha-32` | 32% | Strong brand tint |
256
+ | `--primitive-blue-alpha-40` | 40% | Slider range fill (via `--slider-range`) |
257
+ | `--primitive-blue-alpha-50` | 50% | Brand overlay |
258
+ | `--primitive-blue-alpha-64` | 64% | Heavy brand overlay |
259
+ | `--primitive-blue-alpha-80` | 80% | Near-opaque brand overlay |
260
+
261
+ > **`--primitive-black-50` is deprecated.** It now aliases `--primitive-mono-alpha-50`. The `--overlay` semantic token is unaffected — it still resolves to the same 50% black value.
262
+
263
+ ---
264
+
265
+ ## 3 — AI Agent Decision Rules
266
+
267
+ > Quick-lookup table: "If I need X, use Y, never Z."
268
+
269
+ | IF you need to... | THEN use | NEVER use |
270
+ | -------------------------------------- | --------------------------------- | -------------------------------------- |
271
+ | Pick a primary CTA button color | `bg-primary` | Green, or any other color for primary CTA |
272
+ | Show WIN / profit / positive | `text-semantic-win` | Primary blue for profit |
273
+ | Show LOSS / negative | `text-semantic-loss` | Any non-token red |
274
+ | Show WARNING / caution | `text-semantic-warning` | Raw orange hex or primary tint |
275
+ | Color a tab container background | `bg-tabs` | `bg-subtle` for tabs |
276
+ | Color an active/selected tab | `bg-tabs-active` | `bg-prominent` for active tab |
277
+ | Color a page background | `bg-prominent` | `bg-white` directly |
278
+ | Color a modal/dialog backdrop | `bg-overlay` | `bg-black/50` or raw black opacity |
279
+ | Color a card or panel | `bg-card` | Arbitrary gray |
280
+ | Color an elevated surface (popover) | `bg-popover` | `bg-card` for popovers |
281
+ | Write primary heading text | `text-on-prominent` | Pure white, raw hex colors |
282
+ | Write body / description text | `text-on-subtle` | `text-on-prominent` for descriptions |
283
+ | Write a subtle label | `text-on-subtle` | Raw gray values |
284
+ | Add a default border | `border-border-subtle` | Solid black borders, `border-border` |
285
+ | Add a strong border | `border-border-prominent` | — |
286
+ | Style an input (resting) | `border-input` | Solid colored backgrounds |
287
+ | Style an input (focused) | `border-ring` + `ring-[3px] ring-ring/50` | Generic shadows on inputs |
288
+ | Pick a heading font | `font-display` | System fonts, raw font-family names |
289
+ | Pick a body font | `font-body` | Raw font-family names |
290
+ | Style button text | `font-display font-bold`, sentence case | `uppercase` on buttons |
291
+ | Write white text on a dark surface | `text-on-prominent-static-inverse`| `text-white` or raw white hex |
292
+
293
+ ---
294
+
295
+ ## 4 — Typography
296
+
297
+ ### 4.1 — Font Setup
298
+
299
+ All text uses **Plus Jakarta Sans** (loaded weights: 300–800). Three Tailwind aliases are available — they all resolve to the same font:
300
+
301
+ | Tailwind Class | Purpose |
302
+ | --------------- | ------------------------------- |
303
+ | `font-display` | Headings, wordmark, buttons |
304
+ | `font-body` | Body text, UI elements |
305
+ | `font-sans` | Default sans-serif fallback |
306
+
307
+ ### 4.2 — Pre-built Typography Classes
308
+
309
+ The npm package ships these ready-to-use CSS classes. All include `text-transform: uppercase`:
310
+
311
+ | Class | Size | Line Height | Weight | Letter Spacing |
312
+ | ------------- | ----- | ----------- | ------ | -------------- |
313
+ | `heading-h1` | 72px | 72px | 600 | 1.5px |
314
+ | `heading-h2` | 64px | 64px | 600 | 1.5px |
315
+ | `heading-h3` | 48px | 48px | 600 | 1.5px |
316
+ | `heading-h4` | 40px | 40px | 600 | 1.5px |
317
+ | `heading-xs` | 24px | 24px | 600 | 1.5px |
318
+ | `body-lg` | 18px | 28px | 600 | — |
319
+ | `body-md` | 16px | 24px | 600 | — |
320
+ | `body-sm` | 12px | 16px | 600 | — |
321
+ | `body-xs` | 8px | 12px | 600 | — |
322
+
323
+ **Responsive heading sizes** (headings scale down on mobile):
324
+
325
+ | Class | Desktop | Mobile |
326
+ | ------------ | ------- | ------ |
327
+ | `heading-h1` | 72px | 48px |
328
+ | `heading-h2` | 64px | 48px |
329
+ | `heading-h3` | 48px | 40px |
330
+ | `heading-h4` | 40px | 32px |
331
+ | `heading-xs` | 24px | 20px |
332
+
333
+ ### 4.3 — Custom Text Size Overrides
334
+
335
+ These sizes differ from standard Tailwind defaults — use the design system values:
336
+
337
+ | Class | Size | Line Height | How it differs from Tailwind |
338
+ | ----------- | ------ | ----------- | ---------------------------- |
339
+ | `text-xxs` | 8px | 12px | Custom (not in standard TW) |
340
+ | `text-2xl` | 24px | **24px** | Line height differs (TW: 32px) |
341
+ | `text-3xl` | **32px** | **32px** | Size differs (TW: 30px) |
342
+ | `text-4xl` | **40px** | **40px** | Size differs (TW: 36px) |
343
+ | `text-6xl` | **64px** | **64px** | Size differs (TW: 60px) |
344
+
345
+ > All other `text-*` sizes (`xs`, `sm`, `base`, `lg`, `xl`, `5xl`, `7xl`, `8xl`, `9xl`) match standard Tailwind.
346
+
347
+ ### 4.4 — Typography Usage Rules
348
+
349
+ | Context | Class | Weight |
350
+ | ------------------------ | -------------- | ------------------- |
351
+ | Page headings | `font-display` | `font-semibold` (600) |
352
+ | Button labels | `font-display` | `font-bold` (700), sentence case |
353
+ | Body text | `font-body` | `font-semibold` (600) |
354
+ | Tiny labels / decorative | `font-body` | `font-semibold` (600) at 8px |
355
+
356
+ ### 4.5 — Letter Spacing Tokens
357
+
358
+ | Token value | Usage |
359
+ | ----------- | ------------------------ |
360
+ | 1.5px | Buttons, headings |
361
+ | -0.4px | Paragraphs, tight text |
362
+ | -0.8px | Tight display text |
363
+
364
+ ---
365
+
366
+ ## 5 — Border Radius
367
+
368
+ The design system uses a custom radius scale (base = 10px). Use these named tokens instead of arbitrary values:
369
+
370
+ | Tailwind Class | Value |
371
+ | -------------- | ------ |
372
+ | `rounded-2xs` | 2px |
373
+ | `rounded-xs` | 4px |
374
+ | `rounded-sm` | 6px |
375
+ | `rounded-md` | 8px |
376
+ | `rounded-lg` | 10px |
377
+ | `rounded-xl` | 14px |
378
+ | `rounded-2xl` | 18px |
379
+ | `rounded-3xl` | 22px |
380
+ | `rounded-4xl` | 26px |
381
+ | `rounded-full` | 9999px |
382
+
383
+ > **Important:** Do NOT use `rounded-[4px]` or `rounded-[2px]` — use `rounded-xs` and `rounded-2xs` instead. Arbitrary radius values should only be used for sizes not in this scale (e.g. `rounded-[24px]`, `rounded-[32px]`).
384
+
385
+ ---
386
+
387
+ ## 6 — Button System
388
+
389
+ ### 6.1 — Variants
390
+
391
+ | Variant | Background | Text Color | Border | Hover |
392
+ | ----------- | ---------------------- | ---------------------------------- | ----------------------------------- | ----------------------- |
393
+ | `primary` | `bg-primary` | `text-on-prominent-static-inverse` | none | `bg-primary-hover` |
394
+ | `secondary` | transparent | `text-on-prominent` | `border-[1.5px] border-border-prominent` | `bg-secondary-hover` |
395
+ | `tertiary` | transparent | `text-primary` | none | `bg-primary/[0.08]` |
396
+
397
+ ### 6.2 — Sizes
398
+
399
+ | Size | Height | Padding X | Font Size | Icon Size | Radius |
400
+ | --------- | ------ | --------- | --------- | --------- | ------ |
401
+ | `lg` | 48px | 24px | 16px | 16px | 4px |
402
+ | `md` | 40px | 16px | 14px | 16px | 4px |
403
+ | `sm` | 32px | 12px | 12px | 14px | 4px |
404
+ | `xs` | 24px | 8px | 12px | 12px | 4px |
405
+
406
+ **Icon-only sizes:**
407
+
408
+ | Size | Dimensions | Icon Size |
409
+ | ---------- | ---------- | --------- |
410
+ | `icon-lg` | 48×48px | 16px |
411
+ | `icon-md` | 40×40px | 16px |
412
+ | `icon-sm` | 28×28px | 16px |
413
+ | `icon-xs` | 24×24px | 12px |
414
+
415
+ ### 6.3 — Button Typography & States
416
+
417
+ All buttons: `font-display font-bold`, sentence case (no `uppercase`, no `tracking-wide`).
418
+
419
+ | State | Behavior |
420
+ | -------- | ------------------------------------------------ |
421
+ | Default | Base styling per variant |
422
+ | Hover | Color shift per variant (see above) |
423
+ | Focus | 3px ring with `ring-ring/50` opacity |
424
+ | Pressed | `active:opacity-60` |
425
+ | Loading | `opacity-24`, `pointer-events-none`, `data-loading`, `aria-busy` — applies to all variants (primary, secondary, tertiary) |
426
+ | Disabled | `opacity-24`, `pointer-events-none` — applies to all variants (primary, secondary, tertiary) |
427
+
428
+ ---
429
+
430
+ ## 7 — Responsive Layout
431
+
432
+ ### 7.1 — Layout Grid
433
+
434
+ | Breakpoint | Viewport | Columns | Gutter | Margin |
435
+ | ---------- | ---------- | ------- | ------ | ------ |
436
+ | Default | 0–319px | 1 | 0 | 16px |
437
+ | Small | 320–599px | 4 | 16px | 16px |
438
+ | Medium | 600–1135px | 8 | 36px | 36px |
439
+ | Large | 1136px+ | 12 | 36px | 64px |
440
+
441
+ **Tailwind utilities:** `gap-layout-gutter`, `px-layout-margin-inline`.
442
+
443
+ **CSS variables for custom grids:** `var(--semantic-layout-grid-columns)`, `var(--spacing-layout-gutter)`, `var(--spacing-layout-margin-inline)`.
444
+
445
+ ### 7.2 — Responsive Spacing Tokens
446
+
447
+ | Token | Desktop | Mobile |
448
+ | -------------------- | ------- | ------ |
449
+ | container-padding-x | 24px | 16px |
450
+ | section-padding-y | 96px | 64px |
451
+ | section-title-gap-xl | 24px | 20px |
452
+ | section-title-gap-lg | 20px | 16px |
453
+ | section-title-gap-md | 20px | 16px |
454
+ | section-title-gap-sm | 16px | 16px |
455
+
456
+ ---
457
+
458
+ ## 8 — Available Components
459
+
460
+ > **All components below are exported from `@trading-game/design-intelligence-layer`.**
461
+ > - If a component is listed → import and use it. Do NOT re-implement.
462
+ > - If NOT listed → STOP and ask the user (see Rule 1).
463
+ > - For props, variants, sizes, and sub-components → inspect the package's TypeScript types after installation.
464
+
465
+ ### Import pattern
466
+
467
+ All components use the same import path:
468
+
469
+ ```tsx
470
+ import { Button, Card, Badge } from "@trading-game/design-intelligence-layer"
471
+ ```
472
+
473
+ ### Example — composed component with sub-components
474
+
475
+ ```tsx
476
+ import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose } from "@trading-game/design-intelligence-layer"
477
+
478
+ <Dialog>
479
+ <DialogTrigger asChild><Button>Open</Button></DialogTrigger>
480
+ <DialogContent showCloseButton>
481
+ <DialogHeader>
482
+ <DialogTitle>Title</DialogTitle>
483
+ <DialogDescription>Description text.</DialogDescription>
484
+ </DialogHeader>
485
+ <div>Content here</div>
486
+ <DialogFooter>
487
+ <Button variant="primary" size="md">Confirm</Button>
488
+ </DialogFooter>
489
+ </DialogContent>
490
+ </Dialog>
491
+ ```
492
+
493
+ ### Component list
494
+
495
+ > **Complexity tags:** `[simple]` = drop in, one import | `[composed]` = has required sub-components | `[complex]` = has significant state/setup, ask the user first
496
+
497
+ | Component | Tag | Sub-components |
498
+ |-----------|-----|----------------|
499
+ | Accordion | [composed] | AccordionItem, AccordionTrigger, AccordionContent |
500
+ | Alert | [composed] | AlertTitle, AlertDescription |
501
+ | AlertDialog | [complex] | AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, AlertDialogMedia |
502
+ | AspectRatio | [simple] | — |
503
+ | Avatar | [composed] | AvatarImage, AvatarFallback, AvatarBadge, AvatarGroup, AvatarGroupCount |
504
+ | Badge | [simple] | — |
505
+ | Breadcrumb | [composed] | BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis |
506
+ | Button | [simple] | — |
507
+ | Calendar | [complex] | — |
508
+ | Card | [composed] | CardHeader, CardTitle, CardDescription, CardContent, CardFooter, CardAction |
509
+ | Carousel | [complex] | CarouselContent, CarouselItem, CarouselPrevious, CarouselNext |
510
+ | Chart | [complex] | ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent, ChartStyle |
511
+ | Checkbox | [simple] | — |
512
+ | Collapsible | [composed] | CollapsibleTrigger, CollapsibleContent |
513
+ | Combobox | [complex] | ComboboxInput, ComboboxContent, ComboboxList, ComboboxItem, ComboboxEmpty, ComboboxGroup, ComboboxLabel |
514
+ | Command | [complex] | CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator, CommandShortcut |
515
+ | ContextMenu | [composed] | ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuLabel, ContextMenuCheckboxItem, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent |
516
+ | Dialog | [complex] | DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, DialogClose |
517
+ | DirectionProvider | [simple] | — |
518
+ | Drawer | [complex] | DrawerTrigger, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription, DrawerClose |
519
+ | DropdownMenu | [composed] | DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuShortcut |
520
+ | Empty | [composed] | EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent |
521
+ | Field | [complex] | FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSet, FieldContent, FieldTitle, FieldSeparator |
522
+ | Form | [complex] | FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage |
523
+ | HoverCard | [composed] | HoverCardTrigger, HoverCardContent |
524
+ | Input | [simple] | — |
525
+ | InputGroup | [composed] | InputGroupAddon, InputGroupInput, InputGroupButton, InputGroupText, InputGroupTextarea |
526
+ | InputOTP | [composed] | InputOTPGroup, InputOTPSlot, InputOTPSeparator |
527
+ | Item | [composed] | ItemGroup, ItemContent, ItemTitle, ItemDescription, ItemMedia, ItemActions, ItemHeader, ItemFooter, ItemSeparator |
528
+ | Kbd | [simple] | KbdGroup |
529
+ | Label | [simple] | — |
530
+ | Link | [simple] | — |
531
+ | Menubar | [complex] | MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem, MenubarSeparator, MenubarLabel, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarSub, MenubarSubTrigger, MenubarSubContent, MenubarShortcut |
532
+ | NavigationMenu | [complex] | NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, navigationMenuTriggerStyle |
533
+ | NativeSelect | [simple] | NativeSelectOption, NativeSelectOptGroup |
534
+ | Pagination | [composed] | PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis |
535
+ | Popover | [composed] | PopoverTrigger, PopoverContent, PopoverHeader, PopoverTitle, PopoverDescription |
536
+ | Progress | [simple] | — |
537
+ | RadioGroup | [composed] | RadioGroupItem |
538
+ | Resizable | [complex] | ResizablePanelGroup, ResizablePanel, ResizableHandle |
539
+ | ScrollArea | [simple] | ScrollBar |
540
+ | Select | [composed] | SelectTrigger, SelectValue, SelectContent, SelectGroup, SelectLabel, SelectItem, SelectSeparator |
541
+ | Separator | [simple] | — |
542
+ | Sheet | [complex] | SheetTrigger, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription, SheetClose |
543
+ | Sidebar | [complex] | SidebarProvider, SidebarTrigger, SidebarInset, SidebarHeader, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarGroupContent, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarRail, useSidebar |
544
+ | Skeleton | [simple] | — |
545
+ | Slider | [simple] | — |
546
+ | Sonner (Toaster) | [simple] | — (also import `toast` from `sonner`) |
547
+ | Spinner | [simple] | — |
548
+ | Stepper | [simple] | — |
549
+ | Switch | [simple] | — |
550
+ | Table | [composed] | TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption |
551
+ | Tabs | [composed] | TabsList (`variant`: default/line, `size`: sm/md/lg), TabsTrigger (`iconPosition`: inline/top), TabsContent. Root accepts `orientation`: horizontal/vertical. |
552
+ | Textarea | [simple] | — |
553
+ | TicketCard | [composed] | — |
554
+ | Toggle | [simple] | — |
555
+ | ToggleGroup | [composed] | ToggleGroupItem |
556
+ | Tooltip | [composed] | TooltipTrigger, TooltipContent, TooltipProvider |
557
+
558
+ ### Component styling notes
559
+
560
+ These are styling behaviors you can't discover from TypeScript types alone:
561
+
562
+ | Component | Note |
563
+ |-----------|------|
564
+ | Button | `font-display font-bold`, sentence case (no `uppercase`). Primary: `text-on-prominent-static-inverse`. Tertiary hover: `bg-primary/[0.08]` |
565
+ | Card | Flat by default (no shadow). Add elevation manually: `className="shadow-sm"` |
566
+ | Input | Resting: `border-input`. Focus: `border-ring` + `ring-[3px] ring-ring/50`. Radius: `rounded-sm` (6px) |
567
+ | Tooltip | Bubble: `bg-primary` + `text-on-prominent-static-inverse` (not `bg-popover`). Always wrap in `<TooltipProvider>` |
568
+ | Sidebar | Menu buttons use `rounded-sm`. Selection: `bg-secondary-hover` + `text-primary` + `font-semibold` |
569
+ | Breadcrumb | Active page: `text-primary font-medium`. Links: `text-on-subtle` |
570
+ | Tabs | **Variants:** `default` (pill, `bg-tabs`) and `line` (underline, transparent bg). **Sizes:** `sm` (h-8, text-xs), `md` (h-10, text-sm, default), `lg` (h-12, text-base). **Icon position:** `inline` (default) or `top` (stacks icon above label). **Orientation:** `horizontal` (default) or `vertical` (line variant renders left-edge indicator). Hover: `bg-secondary-hover` (default) / `text-primary` (line). Selected: `bg-tabs-active` + `text-primary font-semibold`. Line variant underline: `bg-primary`. |
571
+ | Select | Item hover: `bg-primary/[0.08]`. Selected: `text-primary font-medium` + checkmark. `SelectTrigger` accepts `readOnly` prop: blocks interaction, retains full default appearance, chevron renders at `opacity-30` |
572
+ | Progress | Track: `bg-primary/20`. Indicator: `bg-primary`. Radius: `rounded-2xs` |
573
+ | Spinner | Inherits parent text color. **Always pass `text-primary` for standalone use** |
574
+ | Stepper | Numeric input flanked by `−` / `+` tertiary `icon-xs` buttons. Composes `InputGroup` internally. Props: `value`, `defaultValue`, `onValueChange`, `min`, `max`, `step` (default 1), `disabled`, `placeholder`. Supports controlled & uncontrolled modes, keyboard Arrow Up/Down, and floating-point steps. Default width: `w-32` |
575
+ | Switch | Checked track: `bg-slider-range`. Checked thumb: `bg-primary` |
576
+ | Slider | Thumb: square `rounded-[4px]`, `bg-primary`. Track range: `bg-slider-range` |
577
+ | Dialog/Sheet | Footer buttons should use `size="md"`. Overlay: `bg-overlay` |
578
+ | Menubar | Hover: `bg-primary/[0.08]`. Open state: `bg-primary/10` |
579
+ | Toggle | Pressed: `bg-primary/10` + `border-primary` + `text-primary` |
580
+ | Calendar | Selected: `bg-secondary-hover` + `text-primary font-bold`. Today: primary dot below date |
581
+
582
+ ---
583
+
584
+ ## 8.5 — Blocks Catalogue
585
+
586
+ > Blocks are fully composed UI sections built from design system primitives. They appear in the **Blocks** tab of the playground.
587
+ > - Blocks are **NOT exported** from the npm package — they are playground demonstrations only.
588
+ > - To build them in a consuming project, import the underlying components (`Button`, etc.) from `@trading-game/design-intelligence-layer` and compose them manually using design tokens only.
589
+ > - Do NOT mistake a Block for a component — it will not appear in Rule 1's component list.
590
+
591
+ ### NavBar
592
+
593
+ A landing page top navigation bar with Desktop and Mobile breakpoint variants.
594
+
595
+ | Variant | Description |
596
+ |---------|-------------|
597
+ | Desktop | Full-width bar: logo left, ghost nav links centre-left, Sign in (ghost) + Sign up (primary) right |
598
+ | Mobile — closed | Logo left, hamburger icon-button right |
599
+ | Mobile — open | Logo + close icon top row; stacked ghost nav links + full-width Sign in / Sign up below a divider |
600
+
601
+ **Components used:** `Button` (variants: `ghost`, `primary`, `secondary`; sizes: `sm`, `icon-sm`)
602
+
603
+ **Tokens used:** `bg-prominent`, `bg-primary`, `border-border-subtle`, `rounded-xs`, `rounded-md`
604
+
605
+ ---
606
+
607
+ ### Hero
608
+
609
+ Landing page hero sections in multiple layout types.
610
+
611
+ | Variant | Description |
612
+ |---------|-------------|
613
+ | Type 1 — Desktop | Two columns: tagline pill + heading + body + Get started / Learn more CTAs left; square image panel right |
614
+ | Type 1 — Mobile | Single column stacked: text content centred above, image panel full-width below |
615
+ | Type 2 — Desktop | Centred single-column: tagline pill + heading + body + single primary CTA with `ArrowRight` icon; no image |
616
+
617
+ **Components used:** `Button` (default `sm`, `secondary sm`); `ArrowUpRight`, `ArrowRight` icons (lucide)
618
+
619
+ **Tokens used:** `bg-prominent`, `bg-subtle`, `border-border-subtle`, `text-on-prominent`, `text-on-subtle`, `bg-semantic-win`, `rounded-xl`, `rounded-full`, `px-layout-margin-inline`, `gap-layout-gutter`, `py-24`, `text-5xl`, `font-semibold`, `font-display`, `tracking-tight`, `text-lg`, `font-body`, `text-sm`, `shadow-sm`, `max-w-2xl`
620
+
621
+ ---
622
+
623
+ ## 9 — Common Mistakes
624
+
625
+ | Mistake | Correct Approach |
626
+ | ------- | ---------------- |
627
+ | Using hardcoded hex (`#2323FF`) for primary | Use `bg-primary` or `text-primary` |
628
+ | Using `bg-white` or `bg-black` | Use `bg-prominent` or `bg-overlay` |
629
+ | Using `border-border` | Use `border-border-subtle` or `border-border-prominent` |
630
+ | Using `bg-hover` | Use `bg-primary/[0.08]` or `bg-secondary-hover` |
631
+ | Using `text-primary-foreground` | Use `text-on-prominent-static-inverse` |
632
+ | Using `text-on-decorative` | Use `text-on-subtle` |
633
+ | Using `font-mono` expecting Plus Jakarta Sans | Use `font-display` or `font-body` |
634
+ | Using `font-bold` for headings | Use `font-semibold` (600) for headings |
635
+ | Using `uppercase` on buttons | Buttons use sentence case (no `uppercase`) |
636
+ | Using standard TW sizes for headings (e.g. `text-6xl` = 60px) | Use design system values (`text-6xl` = 64px in this system) |
637
+ | Forgetting responsive heading sizes | Headings scale down on mobile (see Section 4.2) |
638
+ | Using `rounded-[4px]` or `rounded-[2px]` | Use `rounded-xs` (4px) or `rounded-2xs` (2px) |
639
+ | Installing `lucide-react` separately | Already bundled — import icons directly |
640
+ | Adding `tailwind.config.js` | Tailwind v4 uses CSS config via the package |
641
+ | Using `bg-gray-*`, `text-zinc-*`, etc. | Use semantic tokens only |
642
+
643
+ ---
644
+
645
+ ## 10 — Accessibility Notes
646
+
647
+ 1. **Primary blue text on white** (~3.0:1) — reserve for large/bold UI labels only.
648
+ 2. **Secondary text `text-on-subtle` on white** (~4.5:1) — meets WCAG AA for normal text.
649
+ 3. **Secondary text `text-on-subtle` on white** (~4.5:1) — meets WCAG AA for normal text.
650
+ 4. **Win green on white** (~5.0:1) — safe for normal text at AA.
651
+ 5. **Loss red on white** (~3.9:1) — use at 18px+ bold or pair with icons.
652
+ 6. Always pair semantic colors with **icons or labels** — never communicate meaning through color alone.
653
+
654
+ ---
655
+
656
+ ## Quick Reference — Code Snippets
657
+
658
+ **Primary CTA:**
659
+ ```tsx
660
+ <Button variant="primary" size="lg">Trade Now</Button>
661
+ ```
662
+
663
+ **Profit/Loss display:**
664
+ ```tsx
665
+ <span className="text-semantic-win font-body font-semibold">+$84.00</span>
666
+ <span className="text-semantic-loss font-body font-semibold">-$120.00</span>
667
+ ```
668
+
669
+ **Heading:**
670
+ ```tsx
671
+ <h1 className="heading-h1">Trading Game</h1>
672
+ ```
673
+
674
+ **Body text:**
675
+ ```tsx
676
+ <p className="body-md">Your portfolio summary for today.</p>
677
+ ```
678
+
679
+ **Input with focus styling:**
680
+ ```tsx
681
+ <Input type="email" placeholder="Enter your email" />
682
+ ```