@trading-game/design-intelligence-layer 0.17.3 → 1.0.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 +104 -231
- package/README.md +46 -742
- package/dist/index.cjs +2753 -2985
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +247 -261
- package/dist/index.d.ts +247 -261
- package/dist/index.js +2648 -2855
- package/dist/index.js.map +1 -1
- package/docs/components/accordion.md +85 -0
- package/docs/components/alert-dialog.md +98 -0
- package/docs/components/aspect-ratio.md +55 -0
- package/docs/components/avatar.md +88 -0
- package/docs/components/badge.md +75 -0
- package/docs/components/banner.md +84 -0
- package/docs/components/bottom-navigation.md +90 -0
- package/docs/components/breadcrumb.md +85 -0
- package/docs/components/button.md +94 -0
- package/docs/components/calendar.md +74 -0
- package/docs/components/card.md +79 -0
- package/docs/components/carousel.md +82 -0
- package/docs/components/checkbox.md +66 -0
- package/docs/components/chip.md +72 -0
- package/docs/components/command.md +86 -0
- package/docs/components/context-menu.md +90 -0
- package/docs/components/dialog.md +95 -0
- package/docs/components/drawer.md +97 -0
- package/docs/components/dropdown-menu.md +92 -0
- package/docs/components/empty.md +87 -0
- package/docs/components/field.md +117 -0
- package/docs/components/hover-card.md +77 -0
- package/docs/components/input-group.md +105 -0
- package/docs/components/input-otp.md +87 -0
- package/docs/components/input.md +71 -0
- package/docs/components/item.md +105 -0
- package/docs/components/label.md +56 -0
- package/docs/components/link.md +66 -0
- package/docs/components/menubar.md +102 -0
- package/docs/components/native-select.md +71 -0
- package/docs/components/navigation-button.md +68 -0
- package/docs/components/navigation-menu.md +99 -0
- package/docs/components/numpad.md +78 -0
- package/docs/components/pagination.md +84 -0
- package/docs/components/popover.md +89 -0
- package/docs/components/profile-photo.md +81 -0
- package/docs/components/progress.md +60 -0
- package/docs/components/radio-group.md +82 -0
- package/docs/components/resizable.md +79 -0
- package/docs/components/scroll-area.md +66 -0
- package/docs/components/section-message.md +99 -0
- package/docs/components/select.md +105 -0
- package/docs/components/separator.md +55 -0
- package/docs/components/sheet.md +91 -0
- package/docs/components/sidebar.md +125 -0
- package/docs/components/skeleton.md +51 -0
- package/docs/components/slider.md +61 -0
- package/docs/components/spinner.md +52 -0
- package/docs/components/stepper.md +68 -0
- package/docs/components/switch.md +57 -0
- package/docs/components/table.md +86 -0
- package/docs/components/tabs.md +95 -0
- package/docs/components/textarea.md +58 -0
- package/docs/components/toast.md +66 -0
- package/docs/components/toggle-group.md +77 -0
- package/docs/components/toggle.md +60 -0
- package/docs/components/tooltip.md +83 -0
- package/docs/foundations/colors.md +109 -0
- package/docs/foundations/motion.md +63 -0
- package/docs/foundations/shape-layout.md +56 -0
- package/docs/foundations/typography.md +83 -0
- package/docs/patterns/forms.md +70 -0
- package/docs/patterns/menus.md +50 -0
- package/docs/patterns/on-brand.md +43 -0
- package/guides/audits/design-system-audit-2026-07.md +135 -0
- package/guides/rules/design-system-consuming-project.mdc +56 -0
- package/package.json +6 -7
- package/src/styles.css +1616 -251
- package/guides/design-system-guide/trading-game-ds-guide.md +0 -917
package/AGENTS.md
CHANGED
|
@@ -1,231 +1,104 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
import { HeroBlock } from "@trading-game/design-intelligence-layer"
|
|
106
|
-
|
|
107
|
-
<HeroBlock
|
|
108
|
-
layout="centered" // "centered" | "split"
|
|
109
|
-
tagline={{ label: "What's new", suffix: "v2.0" }}
|
|
110
|
-
heading="Solve your customer's main problem"
|
|
111
|
-
body="One or two sentences expanding on the value prop."
|
|
112
|
-
primaryCta={{ label: "Get started", onClick: ... }}
|
|
113
|
-
secondaryCta={{ label: "Learn more", onClick: ... }} // split layout only
|
|
114
|
-
/>
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### `AuthBlock`
|
|
118
|
-
|
|
119
|
-
Sign-in / sign-up form with OAuth providers, divider, email input, terms, and cross-link.
|
|
120
|
-
|
|
121
|
-
```tsx
|
|
122
|
-
import { AuthBlock } from "@trading-game/design-intelligence-layer"
|
|
123
|
-
|
|
124
|
-
<AuthBlock
|
|
125
|
-
mode="sign-in" // "sign-in" | "sign-up"
|
|
126
|
-
logoSrc="/path/to/brand-icon.svg"
|
|
127
|
-
providers={["google", "telegram", "x"]} // default: all three
|
|
128
|
-
onSubmit={({ email }) => { ... }}
|
|
129
|
-
crossLinkHref="/auth/signup"
|
|
130
|
-
/>
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### `FAQBlock`
|
|
134
|
-
|
|
135
|
-
Eyebrow + heading + intro + accordion + optional "Need more help" card.
|
|
136
|
-
|
|
137
|
-
```tsx
|
|
138
|
-
import { FAQBlock } from "@trading-game/design-intelligence-layer"
|
|
139
|
-
|
|
140
|
-
<FAQBlock
|
|
141
|
-
layout="desktop" // "desktop" | "mobile"
|
|
142
|
-
items={[{ value: "q1", question: "...", answer: "..." }, ...]}
|
|
143
|
-
intro={<>Optional intro paragraph with a <Link>link</Link>.</>}
|
|
144
|
-
helpCard={{ title: "Need more help?", body: "...", ctaLabel: "Contact us" }}
|
|
145
|
-
/>
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### `NavBarBlock`
|
|
149
|
-
|
|
150
|
-
Responsive marketing nav with brand mark, link buttons, sign-in/up CTAs, and an internal mobile drawer.
|
|
151
|
-
|
|
152
|
-
```tsx
|
|
153
|
-
import { NavBarBlock } from "@trading-game/design-intelligence-layer"
|
|
154
|
-
|
|
155
|
-
<NavBarBlock
|
|
156
|
-
brand={{ fullLogoSrc: "...", iconLogoSrc: "...", alt: "Brand" }}
|
|
157
|
-
links={[{ label: "Products" }, { label: "Docs" }, ...]}
|
|
158
|
-
signIn={{ onClick: ... }}
|
|
159
|
-
signUp={{ onClick: ... }}
|
|
160
|
-
/>
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### `HeaderNavigationBlock`
|
|
164
|
-
|
|
165
|
-
In-app trading header (back · badge · balance · history · action slot). History icon supports an overlaid count badge in `bg-primary`.
|
|
166
|
-
|
|
167
|
-
```tsx
|
|
168
|
-
import { HeaderNavigationBlock } from "@trading-game/design-intelligence-layer"
|
|
169
|
-
|
|
170
|
-
<HeaderNavigationBlock
|
|
171
|
-
onBack={() => router.back()}
|
|
172
|
-
badge={{ label: "Demo", variant: "fill-warning" }}
|
|
173
|
-
balance={{ amount: "1000.00", currency: "USDT" }}
|
|
174
|
-
history={{ count: 5, onClick: openHistorySheet }} // count 0 hides badge; >99 shows "99+"
|
|
175
|
-
actions={<SoundToggleButton />}
|
|
176
|
-
/>
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### `OpenPositionsBlock`
|
|
180
|
-
|
|
181
|
-
Responsive Sheet (desktop) / Drawer (mobile) containing a list of game positions. Positions are a discriminated union by `kind`: `"rise-fall" | "swipe" | "box-o" | "digits"`.
|
|
182
|
-
|
|
183
|
-
```tsx
|
|
184
|
-
import { OpenPositionsBlock, Position } from "@trading-game/design-intelligence-layer"
|
|
185
|
-
|
|
186
|
-
const positions: Position[] = [
|
|
187
|
-
{ kind: "rise-fall", direction: "Rise", market: "Vol 100", duration: "30 minutes",
|
|
188
|
-
stake: "1.00 USDT", pnl: "+0.96 USDT", win: true },
|
|
189
|
-
...
|
|
190
|
-
]
|
|
191
|
-
|
|
192
|
-
<OpenPositionsBlock
|
|
193
|
-
trigger={<Button variant="secondary">Active trades</Button>}
|
|
194
|
-
positions={positions}
|
|
195
|
-
sheetTitle="Positions"
|
|
196
|
-
onViewHistory={openHistoryPage}
|
|
197
|
-
/>
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### `ResultBlock`
|
|
201
|
-
|
|
202
|
-
Universal win/loss result card with animated halo + thumb illustration + contract badge + duration badge + CTA. Thumb icons are bundled inside the package.
|
|
203
|
-
|
|
204
|
-
```tsx
|
|
205
|
-
import { ResultBlock } from "@trading-game/design-intelligence-layer"
|
|
206
|
-
|
|
207
|
-
<ResultBlock
|
|
208
|
-
status="win" // "win" | "loss"
|
|
209
|
-
amount="10,000.00"
|
|
210
|
-
currency="USDT"
|
|
211
|
-
contractLabel="Rise"
|
|
212
|
-
duration="2 hours"
|
|
213
|
-
pickedDigit={7} // optional, for Digits contracts
|
|
214
|
-
ctaMode="next-round" // "next-round" | "go-again" | "conversion"
|
|
215
|
-
/>
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### `ResultDialog`
|
|
219
|
-
|
|
220
|
-
Fixed-width system dialog (title + body + two CTAs). Used for messages like "out of balance".
|
|
221
|
-
|
|
222
|
-
```tsx
|
|
223
|
-
import { ResultDialog } from "@trading-game/design-intelligence-layer"
|
|
224
|
-
|
|
225
|
-
<ResultDialog
|
|
226
|
-
title="You're out of balance."
|
|
227
|
-
body="Deposit to keep playing or stay in demo mode."
|
|
228
|
-
primaryLabel="Deposit now"
|
|
229
|
-
secondaryLabel="Stay in demo"
|
|
230
|
-
/>
|
|
231
|
-
```
|
|
1
|
+
# AGENTS.md — Champion Trade Design System
|
|
2
|
+
|
|
3
|
+
Rules of engagement for AI agents building with `@trading-game/design-intelligence-layer` (the package renames to Champion Trade at v1.0). Read this first; deep detail lives in [docs/](./docs/).
|
|
4
|
+
|
|
5
|
+
## Hard rules — never break these
|
|
6
|
+
|
|
7
|
+
1. **Semantic colour tokens only.** Classes like `bg-background-brand-default`, `text-text-subtle-default`, `border-border-default-default`. Never hex, never `bg-blue-500`, never primitives — except alpha primitives for glazes/glass (`bg-(--primitive-white-alpha-24)`).
|
|
8
|
+
2. **Never use deprecated aliases** (`bg-prominent`, `text-on-subtle`, `border-subtle`, `bg-primary`, `text-primary`, `ring-ring`, `bg-subtle`, `secondary-hover`, `destructive`, mono-alpha). They exist only for un-migrated external consumers and die at v1.0.
|
|
9
|
+
3. **No bold.** Semibold (600) is the maximum weight in any component or component-adjacent UI. 700/800 belong to the foundation heading scale only.
|
|
10
|
+
4. **No shadows** on inline components — elevation = hairline borders + surface steps. One sanctioned exception: **floating mobile chrome** (Bottom Navigation) carries the soft ambient `shadow-chrome-default` lift, per the Refined Mobile spec. Never add any other shadow.
|
|
11
|
+
5. **Surfaces are solid.** Alpha is only for state layers on top of a solid base: hover/pressed glazes, glass, scrims, selection washes (light theme only).
|
|
12
|
+
6. **Selection states use the selected family**: `bg-background-brand-selected` + `text-text-brand-selected` + `border-border-brand-selected`. Never `brand-default/10` washes, never `text-brand-default` as selected ink — those fail in dark.
|
|
13
|
+
7. **Dark is not a mirror.** Never build a light-theme construction and assume it inverts. If a token pair doesn't exist for what you need, stop and ask — don't improvise per-theme values in a component.
|
|
14
|
+
8. **Typography via type classes.** Component text uses its `.type-<component>-*` class (backed by private `--<component>-*` tokens). No `text-sm`, no `text-[13px]`, no `font-bold`.
|
|
15
|
+
9. **`.type-*` classes are plain CSS, not utilities**: variants can't gate them (`data-[x]:type-foo` does nothing — pick the class in JSX or write a CSS data-attribute rule), and they beat layered `font-*` utilities.
|
|
16
|
+
10. **Radius encodes element class** — buttons/chips `rounded-full`, icon buttons circles, cards/dialogs `rounded-2xl`, menus `rounded-lg`, menu rows `rounded-md`, inputs `rounded-xs` (deliberate, don't "fix" it).
|
|
17
|
+
11. **Sizes sit on the 32/40/48 rail**, default `md` (40px). Button padding-x = height/2 − 4, gap 8, and padding never changes when icons are hidden.
|
|
18
|
+
12. **Focus** = `focus-visible:ring-[3px] focus-visible:ring-ring-focus-strong` (controls) or `ring-ring-focus-soft` (text fields). Error ring = `ring-ring-error-soft`. Every colour must be a plain named token — no alpha-modified constructions, no colour primitives outside the sanctioned glass-ladder set; `npm run check:tokens` enforces both and diffs the Colors page against styles.css.
|
|
19
|
+
|
|
20
|
+
## Composition patterns
|
|
21
|
+
|
|
22
|
+
- **Forms**: wrap controls in `Field` — `<Field size="sm">` cascades its size into Input / Select / Native Select / Input Group automatically (explicit size on the control wins). Field's `data-invalid` paints label + error red through inheritance. Helper text is 12/16 at every size. See [docs/patterns/forms.md](./docs/patterns/forms.md).
|
|
23
|
+
- **Menus**: Command, Context Menu, Dropdown Menu, Menubar, and Select rows share one look (`--menu-*` family): `rounded-lg` surface panel + hairline, `type-menu-item` rows with the hover glaze, `type-menu-heading` group labels. See [docs/patterns/menus.md](./docs/patterns/menus.md).
|
|
24
|
+
- **On brand/art surfaces**: use the `on-brand` variants (Button `primary/secondary/tertiary-on-brand`, Input/InputGroup `variant="on-brand"`, Link `tone="on-brand"`) and the frost recipe (`variant="frosted-on-brand"` on Button, NavigationButton, and Card); on page surfaces the tinted counterpart is Button `variant="frosted"`. See [docs/patterns/on-brand.md](./docs/patterns/on-brand.md).
|
|
25
|
+
- **State layers**: hover = `bg-background-hover-default` glaze; pressed = `bg-background-pressed-default`; brand fills derive hover/press via the built-in `brand-hover`/`brand-pressed` recipes.
|
|
26
|
+
|
|
27
|
+
## Anti-patterns (seen in the wild — don't repeat)
|
|
28
|
+
|
|
29
|
+
- `data-[state=active]:font-semibold` next to a `.type-*` class → silently loses; use the CSS data-attribute weight rule pattern.
|
|
30
|
+
- `bg-white/5` or any translucent resting surface → use the solid surface tokens.
|
|
31
|
+
- A new component colour token (`--mycomponent-bg`) → forbidden; colour stops at the semantic layer.
|
|
32
|
+
- `position="item-aligned"` on Select → the default is `popper` (list drops below the trigger); don't switch back without a reason.
|
|
33
|
+
- Re-adding `xs` button sizes, Kbd, Collapsible, Ticket Card, Chart, Combobox, Form, or the Badge `glass` variant — all removed by design decisions.
|
|
34
|
+
|
|
35
|
+
## Component index — when to use what
|
|
36
|
+
|
|
37
|
+
Docs: `docs/components/<kebab-name>.md` for every entry.
|
|
38
|
+
|
|
39
|
+
| Component | Use it for |
|
|
40
|
+
|---|---|
|
|
41
|
+
| Accordion | Collapsible FAQ-style content sections |
|
|
42
|
+
| Alert Dialog | Blocking confirm/cancel decisions (destructive actions) |
|
|
43
|
+
| Aspect Ratio | Fixed-ratio media containers |
|
|
44
|
+
| Avatar | User images with fallback initials, groups, count overflow |
|
|
45
|
+
| Badge | Small status/category markers (solid, tint, outline; status = 600 fills) |
|
|
46
|
+
| Banner | Editorial gradient promo panel with art, copy, white pill CTA |
|
|
47
|
+
| Bottom Navigation | Mobile bottom nav, max 4 destinations (3 is the norm) — chrome frost bar, liquid selection bubble; the phone counterpart of Sidebar |
|
|
48
|
+
| Breadcrumb | Hierarchical location trail |
|
|
49
|
+
| Button | All actions; variants primary / secondary / tertiary / on-brand family / frosted + frosted-on-brand; `shimmer` modifier for headline CTAs |
|
|
50
|
+
| Calendar | Date and range picking with themed dropdown month/year navigation |
|
|
51
|
+
| Card | Content shells (`default`, `frosted-on-brand`, `interactive` hover-lift); blank by design, slots supply content |
|
|
52
|
+
| Carousel | Horizontally scrolling content (mobile catalogue) |
|
|
53
|
+
| Chip | Compact choice pills: quick amounts, single-select filters, outline error-recovery |
|
|
54
|
+
| Checkbox | Boolean form input |
|
|
55
|
+
| Command | Searchable command palette (menu family) |
|
|
56
|
+
| Context Menu | Right-click menus (menu family) |
|
|
57
|
+
| Dialog | Centred modal panels for tasks/forms |
|
|
58
|
+
| Drawer | Bottom/top/side sheets on mobile (vaul); grab handle on bottom |
|
|
59
|
+
| Dropdown Menu | Click-triggered action menus (menu family) |
|
|
60
|
+
| Empty | Zero-state placeholder with icon tile, title, action |
|
|
61
|
+
| Field | Form field wrapper: label + control + helper/error, size cascade |
|
|
62
|
+
| Hover Card | Rich hover preview panel (a floating card) |
|
|
63
|
+
| Input | Single-line text field; sizes sm/md/lg; `on-brand` variant |
|
|
64
|
+
| Input Group | Things inside a field: prefix/suffix text, icons, pill buttons |
|
|
65
|
+
| Input OTP | Segmented one-time-code entry |
|
|
66
|
+
| Item | List rows with media/title/description/actions (default, outline, muted) |
|
|
67
|
+
| Label | Form label (14/medium); colour inherits so Field error ink flows through |
|
|
68
|
+
| Link | Inline/standalone links — quiet at rest, underline + darker ink on hover; `tone="on-brand"` |
|
|
69
|
+
| Menubar | Horizontal app menu bar (menu family) |
|
|
70
|
+
| Native Select | Styled native `<select>` for OS-native picking; same rail as Input |
|
|
71
|
+
| Navigation Button | Circular icon-only nav control; `frosted-on-brand` variant for art surfaces |
|
|
72
|
+
| Navigation Menu | Marketing-style nav with dropdown panels (menu family type) |
|
|
73
|
+
| Numpad | Mobile amount-entry tray: bare 3×4 grid, emits keys, long-press backspace clears |
|
|
74
|
+
| Pagination | Page navigation; circular cells, brand-selected active page |
|
|
75
|
+
| Popover | Click-triggered floating card for small forms/details |
|
|
76
|
+
| Profile Photo | Avatar with verification ring, camera slot, status badge |
|
|
77
|
+
| Progress | Determinate progress bar (brand fill on 20% wash track) |
|
|
78
|
+
| Radio Group | Single choice among few options |
|
|
79
|
+
| Resizable | Split-pane layouts with drag handles |
|
|
80
|
+
| Scroll Area | Custom scrollbars on constrained regions |
|
|
81
|
+
| Section Message | Inline status messaging (info/success/warning/danger; sm/md; row/stack) |
|
|
82
|
+
| Select | Custom dropdown picking (menu family rows; opens below trigger) |
|
|
83
|
+
| Separator | Hairline dividers |
|
|
84
|
+
| Sheet | Side/top/bottom panels (Radix Dialog based, desktop-oriented) |
|
|
85
|
+
| Sidebar | Desktop app navigation rail; selected rows use the selected family |
|
|
86
|
+
| Skeleton | Loading placeholders (solid secondary surface, pulse) |
|
|
87
|
+
| Slider | Value selection on a track; circular brand thumb |
|
|
88
|
+
| Spinner | Loading indicator (currentColor, 8-blade fade) |
|
|
89
|
+
| Stepper | Numeric +/− input built on Input Group |
|
|
90
|
+
| Switch | On/off toggle; brand track when checked, static white thumb |
|
|
91
|
+
| Table | Data tables; 14px cells, medium heads, hover glaze rows |
|
|
92
|
+
| Tabs | Segmented control (`default` pill-on-track) or underline (`line`) |
|
|
93
|
+
| Textarea | Multi-line text (mirrors Input md) |
|
|
94
|
+
| Toast | Transient notifications (sonner, inverse surface) |
|
|
95
|
+
| Toggle / Toggle Group | Pressed-state buttons and grouped segmented toggles |
|
|
96
|
+
| Tooltip | Hover hints; inverse surface default, bordered-white `inverse` variant; renders as a Drawer on mobile |
|
|
97
|
+
|
|
98
|
+
**Blocks** (`components/blocks/`: NavBar, Hero, Auth, FAQ, Header Navigation, Open Positions, Result, Game Loading) are pre-composed sections — currently awaiting their token-migration pass; prefer components until then.
|
|
99
|
+
|
|
100
|
+
## Demo & source of truth
|
|
101
|
+
|
|
102
|
+
- `npm run dev` → localhost:4000 — every component in light/dark.
|
|
103
|
+
- Token definitions: `src/styles.css` (mirrored in `app/globals.css` — **edit both**).
|
|
104
|
+
- Turbopack gotcha: token/class changes need a full `.next/` wipe + restart, not just HMR.
|