@trading-game/design-intelligence-layer 1.0.0 → 1.0.2

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.
@@ -6,7 +6,7 @@ Binary on/off toggle (Radix Switch) with a sliding white thumb.
6
6
 
7
7
  - Settings that take effect immediately — notifications on/off, dark mode, one-click trading.
8
8
 
9
- **When not:** For options submitted with a form use Checkbox. For selecting one of several visible options use [Toggle Group](./toggle-group.md).
9
+ **When not:** For options submitted with a form use Checkbox. For selecting one of several visible options use [Toggle Group](./toggle.md).
10
10
 
11
11
  ## Anatomy
12
12
 
@@ -6,7 +6,7 @@ Peer-view switcher (Radix Tabs) with a filled-pill default variant and a brand-u
6
6
 
7
7
  - Switching between sibling views of equal weight — Buy/Sell, chart intervals, account sections.
8
8
 
9
- **When not:** For navigation between routes use Navigation Menu or [Sidebar](./sidebar.md). For toggling values that stay on screen use [Toggle Group](./toggle-group.md).
9
+ **When not:** For navigation between routes use Navigation Menu or [Sidebar](./sidebar.md). For toggling values that stay on screen use [Toggle Group](./toggle.md).
10
10
 
11
11
  ## Anatomy
12
12
 
@@ -1,40 +1,70 @@
1
1
  # Toggle
2
2
 
3
- Two-state pressable button (Radix Toggle) whose on-state uses the hover glaze plus brand-selected ink.
3
+ Two-state pressable button (Radix Toggle) wearing the Chip colour treatment on its rectangle: bordered primary surface at rest, solid brand with on-brand ink when on. Same shape as always — only the colours are chip. **Toggle Group** joins several of them into a segmented set and is documented here — one look, shared geometry, one page.
4
4
 
5
5
  ## When to use
6
6
 
7
7
  - A single on/off tool control — bold in an editor, favourite a market, show/hide an overlay.
8
+ - A group for exclusive or multi-select among a few peer options that stay visible — chart interval (1m/5m/1h), order side, view density.
8
9
 
9
- **When not:** For exclusive or multiple selection across several options use [Toggle Group](./toggle-group.md). For settings that apply immediately use [Switch](./switch.md).
10
+ **When not:** For switching content panels use [Tabs](./tabs.md). For settings that apply immediately use [Switch](./switch.md). For 5+ options use [Select](./select.md).
10
11
 
11
12
  ## Anatomy
12
13
 
13
- - `Toggle` — Radix root styled by `toggleVariants` (cva, exported and reused by Toggle Group); `data-slot="toggle"`, `data-state="on|off"`.
14
+ - `Toggle` — Radix root styled by `toggleVariants` (cva, exported); `data-slot="toggle"`, `data-state="on|off"`.
15
+ - `ToggleGroup` — Radix root; publishes `size`/`spacing` through context and sets `--gap`; `data-slot="toggle-group"` with `data-size`, `data-spacing`.
16
+ - `ToggleGroupItem` — one segment, styled by the shared `toggleVariants`; `data-slot="toggle-group-item"`, `data-state="on|off"`.
14
17
 
15
18
  ## API
16
19
 
20
+ ### Toggle
21
+
17
22
  | Prop | Type | Default | Notes |
18
23
  | --- | --- | --- | --- |
19
- | `variant` | `"default" \| "outline"` | `"default"` | default is transparent at rest; outline adds `border-border-prominent-default`. |
20
24
  | `size` | `"default" \| "sm" \| "lg"` | `"default"` | default `h-10 min-w-10 px-2.5` (40px), sm `h-8 min-w-8 px-1.5` (32px), lg `h-12 min-w-12 px-3` (48px) — on the 32/40/48 rail. |
21
25
  | `pressed` / `defaultPressed` | `boolean` | — | Controlled / uncontrolled. |
22
26
  | `onPressedChange` | `(pressed: boolean) => void` | — | Radix callback. |
23
27
 
24
- ## Variants & sizes
28
+ ### ToggleGroup
29
+
30
+ | Prop | Type | Default | Notes |
31
+ | --- | --- | --- | --- |
32
+ | `type` | `"single" \| "multiple"` | — | Radix prop; required. |
33
+ | `size` | as Toggle | — | Inherited by every item via context; context wins over per-item values. |
34
+ | `spacing` | `number` | `0` | Tailwind spacing units between items; `0` = joined segments. |
35
+ | `value` / `defaultValue`, `onValueChange` | Radix props | — | `string` for single, `string[]` for multiple. |
36
+
37
+ ### ToggleGroupItem
38
+
39
+ | Prop | Type | Default | Notes |
40
+ | --- | --- | --- | --- |
41
+ | `value` | `string` | — | Required item identity. |
25
42
 
26
43
  ```tsx
27
- import { Toggle } from "@trading-game/design-intelligence-layer"
44
+ import { Toggle, ToggleGroup, ToggleGroupItem } from "@trading-game/design-intelligence-layer"
28
45
  import { Star } from "lucide-react"
29
46
 
30
47
  <Toggle aria-label="Favourite"><Star /></Toggle>
31
- <Toggle variant="outline" size="sm">1H</Toggle>
32
48
  <Toggle size="lg" pressed={on} onPressedChange={setOn}>Overlay</Toggle>
49
+
50
+ // joined segments (default)
51
+ <ToggleGroup type="single" defaultValue="1h">
52
+ <ToggleGroupItem value="1m">1M</ToggleGroupItem>
53
+ <ToggleGroupItem value="5m">5M</ToggleGroupItem>
54
+ <ToggleGroupItem value="1h">1H</ToggleGroupItem>
55
+ </ToggleGroup>
56
+
57
+ // spaced multiple-select
58
+ <ToggleGroup type="multiple" spacing={2} size="sm">
59
+ <ToggleGroupItem value="ema">EMA</ToggleGroupItem>
60
+ <ToggleGroupItem value="vol">VOL</ToggleGroupItem>
61
+ </ToggleGroup>
33
62
  ```
34
63
 
35
64
  ## Tokens
36
65
 
37
- **Colour (semantic):** `bg-background-hover-default` (hover fill, and the on-state fill — the glaze does double duty), `text-text-prominent-default` (hover ink, outline resting ink), `text-text-brand-selected` (on-state ink), `border-border-prominent-default` (outline variant border; on-state sets `border-transparent`), focus `border-ring-focus-default` + `ring-ring-focus-strong` at 3px, `border-border-error-default` + `ring-error-soft` ring (aria-invalid).
66
+ **Colour (semantic):** the Chip treatment — `border-border-default-default` + `bg-background-primary-surface` + `text-text-prominent-default` (rest), `bg-background-secondary-surface` (hover), `bg-background-secondary-wash` (pressed), on-state `bg-background-brand-default` + `text-text-on-brand-static` with `border-transparent` (the brand flip in dark is the design), focus `border-ring-focus-default` + `ring-ring-focus-strong` at 3px, `border-border-error-default` + `ring-error-soft` ring (aria-invalid).
67
+
38
68
  **Type (private):**
39
69
 
40
70
  | Token | Value |
@@ -43,18 +73,21 @@ import { Star } from "lucide-react"
43
73
 
44
74
  ## Behaviour
45
75
 
46
- - On-state = `bg-background-hover-default` fill + `text-text-brand-selected` ink + transparent border. There is no separate pressed surface token — the hover glaze is reused deliberately.
76
+ - On-state = solid `bg-background-brand-default` fill + `text-text-on-brand-static` ink + transparent border — the Chip selected look.
47
77
  - Radius is `rounded-md` (8px, the row radius); icons default to `size-4`.
78
+ - `spacing={0}` (default) joins segments: items lose their own radius (`rounded-none`), the first/last regain `rounded-l-md`/`rounded-r-md`, and segments share hairlines by dropping `border-l` on all but the first; any positive `spacing` separates them and each keeps `rounded-md`.
79
+ - Items are `w-auto min-w-0 shrink-0 px-3` and raise `z-10` on focus so the ring is never clipped by neighbours.
48
80
  - Disabled: `pointer-events-none opacity-24`.
49
81
 
50
82
  ## Do / Don't
51
83
 
52
84
  **Do**
53
85
  - Give icon-only toggles an `aria-label`.
54
- - Use `outline` when the toggle sits on a busy surface and needs a resting boundary.
86
+ - Keep the group's default `spacing={0}` for segmented-control semantics; use spacing only when items act as independent toggles.
87
+ - Use `type="single"` with a `defaultValue` for interval/side pickers so one option is always on.
55
88
  - Let the exported `toggleVariants` style any custom toggle-like control instead of re-deriving classes.
56
89
 
57
90
  **Don't**
58
- - Don't give the on-state a solid brand fill — the system on-state is glaze + brand-selected ink only.
59
- - Don't exceed medium 500 for the label; the type token is fixed at 14/medium/20.
60
- - Don't use a Toggle where the action navigates or submits — that is a Button.
91
+ - Don't invent variants — one look, three states (rest / hover / on); the former `outline` variant is removed.
92
+ - Don't mix sizes inside one group; the shared border geometry assumes uniform height.
93
+ - Don't use a Toggle where the action navigates or submits — that is a Button; a joined group used for navigation is [Tabs](./tabs.md).
@@ -16,7 +16,7 @@ Token grammar (Quill style): `{element}-{role}-{variant}` — e.g. `background-b
16
16
  2. **Surfaces are always solid.** Alpha values are for *state layers on top of* a solid base (hover glazes, pressed glazes, glass, scrims, washes) — never for a resting surface. Dark surfaces are built as `color-mix()` of white over the canvas, producing a solid colour.
17
17
  3. **Dark is not a mirror.** When a light construction fails on near-black (a 10% wash disappears, mid-blue ink loses contrast), the dark value diverges — that's what the `.dark` block is for. Never hardcode a light construction and assume it flips.
18
18
  4. **Selection states use the `*-brand-selected` family** — never `brand-default/10` washes or `text-brand-default` ink for a selected/active element.
19
- 5. **No shadows anywhere.** Elevation is hairline borders and surface steps.
19
+ 5. **No shadows anywhere,** bar two named exceptions (`shadow-chrome-default` on floating mobile chrome, `shadow-brand-glow` on the Slide to Confirm handle). Elevation is hairline borders and surface steps.
20
20
 
21
21
  ## Primitive scales
22
22
 
@@ -42,6 +42,7 @@ All scales run 50→1000 (mono 50→1200; blue adds 25 and 1000 as the two canva
42
42
  | Token | Light | Dark | Job |
43
43
  |---|---|---|---|
44
44
  | `background-primary-canvas` | blue-25 `#F7F8FC` | blue-1000 `#00001F` | The app page behind everything |
45
+ | `background-tinted-canvas` | blue-600 12%→4% mixed into the canvas + a blue-400 aurora | blue-400 14% into the canvas + aurora | The Refined screen background — a layered gradient, consume via `background: var(--background-tinted-canvas)` on the page root only; ends on `primary-canvas` in both themes so long pages melt in seamlessly |
45
46
  | `background-primary-surface` | mono-50 `#FFFFFF` | white 6% over canvas ≈ `#0F0F2C` | Cards, panels, menus, inputs, sheets — the default solid surface |
46
47
  | `background-secondary-surface` | mono-100 `#F1F1F1` | white 12% over canvas ≈ `#1F1F3A` | One step up: muted fills, tracks, icon tiles, read-only fields |
47
48
  | `background-hover-default` | black-alpha-4 | white-alpha-12 | The hover glaze — laid over any solid surface |
@@ -53,4 +53,4 @@ Tokens: `--semantic-layout-grid-columns`, `--semantic-layout-gutter`, `--semanti
53
53
 
54
54
  ## Elevation
55
55
 
56
- Inline components carry none — **no shadows** — every component's `shadow-*` has been removed. The one sanctioned exception is **floating mobile chrome** (Bottom Navigation): a soft ambient lift (`shadow-chrome-default`, `0 12px 30px`) separates chrome from the content scrolling beneath it, per the Refined Mobile file. Elevation reads through the hairline (`border-default-default`) and surface steps (canvas → primary surface → secondary surface). On dark this is why surfaces are solid white-mixes: the step between `#00001F`, `#0F0F2C`, `#1F1F3A` is the elevation.
56
+ Inline components carry none — **no shadows** — every component's `shadow-*` has been removed. There are exactly two sanctioned exceptions, both per the Refined Mobile file. **Floating mobile chrome** (Bottom Navigation): a soft ambient lift (`shadow-chrome-default`, `0 12px 30px`) separates chrome from the content scrolling beneath it. **The Slide to Confirm handle**: a brand glow (`shadow-brand-glow`, `0 6px 16px` of `background-brand-default` at 35%, so it re-derives per theme) so a committed money action reads as liftable off its track. Neither token may be reused elsewhere. Elevation reads through the hairline (`border-default-default`) and surface steps (canvas → primary surface → secondary surface). On dark this is why surfaces are solid white-mixes: the step between `#00001F`, `#0F0F2C`, `#1F1F3A` is the elevation.
@@ -58,7 +58,7 @@ All text-entry controls share one construction: **hairline border (`border-defau
58
58
  | [Native Select](../components/native-select.md) | OS-native option list, same rail |
59
59
  | [Select](../components/select.md) | custom popup (opens below the trigger) |
60
60
  | [Input OTP](../components/input-otp.md) | segmented code entry |
61
- | [Stepper](../components/stepper.md) | numeric +/− built on Input Group |
61
+ | [Stepper](../components/stepper.md) | the amount tray — frosted −/+ circles, centred editable amount |
62
62
  | [Numpad](../components/numpad.md) | mobile amount entry — pairs with a display figure, not an input |
63
63
 
64
64
  ## Choice cards
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trading-game/design-intelligence-layer",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Trading Game Design System — shadcn/ui components with Tailwind CSS v4",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -30,7 +30,8 @@
30
30
  "start": "next start",
31
31
  "lint": "eslint",
32
32
  "prepublishOnly": "npm run build",
33
- "check:tokens": "node scripts/check-token-docs.mjs"
33
+ "check:tokens": "node scripts/check-token-docs.mjs",
34
+ "predev": "rm -rf .next"
34
35
  },
35
36
  "files": [
36
37
  "dist/",
package/src/styles.css CHANGED
@@ -173,6 +173,9 @@
173
173
  /* ── Named animations ── */
174
174
  --animate-button-shimmer: button-shimmer 4s linear infinite;
175
175
  --animate-skeleton-sweep: skeleton-sweep 1.6s var(--primitive-ease-standard) infinite;
176
+ /* Slide-to-confirm idle nudge — the handle drifts 10px and back, hinting
177
+ the gesture without moving far enough to read as progress. */
178
+ --animate-slide-confirm-nudge: slide-confirm-nudge 1.8s var(--primitive-ease-standard) infinite;
176
179
  }
177
180
 
178
181
  /* ══════════════════════════════════════════════════════════════
@@ -544,6 +547,18 @@
544
547
  /* pressed wash on outline chips */
545
548
  --background-static-white-wash: var(--primitive-white-alpha-80);
546
549
  /* hover on the white on-brand button fills */
550
+ /* Tinted canvas — the screen background: a blue tint melting into the
551
+ canvas with a soft centred aurora — the Refined composition, in token math. One token, two layers; consume via
552
+ `background: var(--background-tinted-canvas)` on the page root (an
553
+ app-shell decision — components never paint it). Every stop is token
554
+ math (blue primitives mixed into the canvas), and both themes end on
555
+ background-primary-canvas so long pages melt in without a seam. */
556
+ --background-tinted-canvas:
557
+ radial-gradient(circle at 50% -10%, color-mix(in srgb, var(--primitive-blue-400) 24%, transparent), transparent 55%),
558
+ linear-gradient(180deg,
559
+ color-mix(in srgb, var(--primitive-blue-600) 12%, var(--background-primary-canvas)) 0%,
560
+ color-mix(in srgb, var(--primitive-blue-600) 4%, var(--background-primary-canvas)) 55%,
561
+ var(--background-primary-canvas) 100%);
547
562
  --background-brand-container:
548
563
  linear-gradient(rgb(255 255 255 / 92%), rgb(255 255 255 / 92%)),
549
564
  var(--primitive-blue-600);
@@ -589,6 +604,10 @@
589
604
  --background-chrome-default: rgb(255 255 255 / 78%);
590
605
  --border-chrome-default: rgb(10 10 60 / 8%);
591
606
  --shadow-chrome-default: 0 12px 30px rgb(10 10 60 / 14%);
607
+ /* Brand-action glow — the second (and only other) sanctioned shadow
608
+ besides floating chrome. Reserved for a committed primary action that
609
+ must read as lifted off its track: the Slide to Confirm handle. */
610
+ --shadow-brand-glow: 0 6px 16px color-mix(in srgb, var(--background-brand-default) 35%, transparent);
592
611
  --text-chrome-subtle: var(--text-subtle-default);
593
612
  --background-chrome-selected:
594
613
  linear-gradient(rgb(255 255 255 / 55%), rgb(255 255 255 / 15%)),
@@ -765,7 +784,7 @@
765
784
  /* Border */
766
785
  --border-default-default: var(--primitive-white-alpha-12);
767
786
  --border-prominent-default: var(--primitive-mono-50);
768
- --border-neutral-default: var(--primitive-white-alpha-12);
787
+ --border-neutral-default: var(--primitive-white-alpha-24);
769
788
 
770
789
  /* Text */
771
790
  --text-prominent-default: var(--primitive-mono-50);
@@ -779,6 +798,11 @@
779
798
  --text-brand-default: var(--primitive-blue-400);
780
799
  --text-brand-hover: var(--primitive-blue-300);
781
800
  --background-brand-selected: color-mix(in srgb, var(--primitive-blue-400) 24%, var(--primitive-blue-1000));
801
+ --background-tinted-canvas:
802
+ radial-gradient(circle at 60% 15%, color-mix(in srgb, var(--primitive-blue-400) 28%, transparent), transparent 55%),
803
+ linear-gradient(180deg,
804
+ color-mix(in srgb, var(--primitive-blue-400) 14%, var(--background-primary-canvas)) 0%,
805
+ var(--background-primary-canvas) 100%);
782
806
  --text-brand-selected: var(--primitive-blue-200);
783
807
  --border-brand-selected: var(--primitive-blue-300);
784
808
  --background-chrome-default: rgb(20 20 44 / 72%);
@@ -786,10 +810,10 @@
786
810
  --shadow-chrome-default: 0 12px 30px rgb(0 0 20 / 50%);
787
811
  --text-chrome-subtle: var(--text-subtle-default);
788
812
  --background-chrome-selected:
789
- linear-gradient(rgb(255 255 255 / 10%), rgb(255 255 255 / 0%)),
790
- var(--background-brand-selected);
791
- --chrome-highlight-default: var(--primitive-white-alpha-24);
792
- --text-chrome-selected: var(--primitive-mono-50);
813
+ linear-gradient(rgb(255 255 255 / 14%), rgb(255 255 255 / 0%)),
814
+ color-mix(in srgb, var(--primitive-blue-400) 45%, var(--primitive-blue-1000));
815
+ --chrome-highlight-default: var(--primitive-white-alpha-32);
816
+ --text-chrome-selected: var(--primitive-blue-100);
793
817
 
794
818
  /* @deprecated aliases that don't resolve through a flipping token */
795
819
  --primary-inverse: var(--primitive-mono-50);
@@ -990,10 +1014,11 @@
990
1014
  --input-line-height-lg: var(--primitive-line-height-24);
991
1015
  --input-font-weight: var(--primitive-font-weight-regular);
992
1016
  /* ── Input OTP — component type tokens (private) ──
993
- Digits ride the input md step (14/regular/20). */
994
- --input-otp-font-size: var(--primitive-font-size-14);
995
- --input-otp-font-weight: var(--primitive-font-weight-regular);
996
- --input-otp-line-height: var(--primitive-line-height-20);
1017
+ Digits ride 20/semibold/28 — larger than the input md step so a
1018
+ 6-digit code reads at a glance. */
1019
+ --input-otp-font-size: var(--primitive-font-size-20);
1020
+ --input-otp-font-weight: var(--primitive-font-weight-semibold);
1021
+ --input-otp-line-height: var(--primitive-line-height-28);
997
1022
  /* ── Native Select — component type tokens (private) ──
998
1023
  Same ladder as Input (12/14/16, regular). */
999
1024
  --native-select-font-size-sm: var(--primitive-font-size-12);
@@ -1037,6 +1062,43 @@
1037
1062
  --bottom-navigation-label-font-weight: var(--primitive-font-weight-medium);
1038
1063
  --bottom-navigation-label-line-height: var(--primitive-line-height-16);
1039
1064
  --bottom-navigation-label-active-font-weight: var(--primitive-font-weight-semibold);
1065
+
1066
+ /* ── Stepper (stake variant) — component type tokens (private) ── */
1067
+ --stepper-stake-label-font-size: var(--primitive-font-size-12);
1068
+ --stepper-stake-label-font-weight: var(--primitive-font-weight-medium);
1069
+ --stepper-stake-label-line-height: var(--primitive-line-height-16);
1070
+ --stepper-stake-amount-font-size: var(--primitive-font-size-24);
1071
+ --stepper-stake-amount-font-weight: var(--primitive-font-weight-semibold);
1072
+ --stepper-stake-amount-line-height: var(--primitive-line-height-32);
1073
+
1074
+ /* ── Progress — component type tokens (private) ── */
1075
+ --progress-label-font-size: var(--primitive-font-size-12);
1076
+ --progress-label-font-weight: var(--primitive-font-weight-semibold);
1077
+ --progress-label-line-height: var(--primitive-line-height-16);
1078
+ --progress-value-font-size: var(--primitive-font-size-14);
1079
+ --progress-value-font-weight: var(--primitive-font-weight-semibold);
1080
+ --progress-value-line-height: var(--primitive-line-height-20);
1081
+
1082
+ /* ── Slide to Confirm — component type tokens (private) ── */
1083
+ --slide-to-confirm-label-font-size: var(--primitive-font-size-14);
1084
+ --slide-to-confirm-label-font-weight: var(--primitive-font-weight-medium);
1085
+ --slide-to-confirm-label-line-height: var(--primitive-line-height-20);
1086
+ --slide-to-confirm-label-confirmed-font-weight: var(--primitive-font-weight-semibold);
1087
+
1088
+ /* ── Steps — component type tokens (private) ── */
1089
+ --steps-indicator-font-size: var(--primitive-font-size-14);
1090
+ --steps-indicator-font-weight: var(--primitive-font-weight-semibold);
1091
+ --steps-indicator-line-height: var(--primitive-line-height-20);
1092
+ --steps-title-font-size: var(--primitive-font-size-14);
1093
+ --steps-title-font-weight: var(--primitive-font-weight-semibold);
1094
+ --steps-title-line-height: var(--primitive-line-height-20);
1095
+ --steps-description-font-size: var(--primitive-font-size-14);
1096
+ --steps-description-font-weight: var(--primitive-font-weight-regular);
1097
+ --steps-description-line-height: var(--primitive-line-height-20);
1098
+ --steps-tag-font-size: var(--primitive-font-size-10);
1099
+ --steps-tag-font-weight: var(--primitive-font-weight-semibold);
1100
+ --steps-tag-line-height: var(--primitive-line-height-16);
1101
+
1040
1102
  /* ── Sidebar — component type tokens (private) ──
1041
1103
  Menu rows 14/regular/20 (sm 12/16); labels + badges 12/medium/16.
1042
1104
  Active rows go semibold via the data-active rule below. */
@@ -1153,7 +1215,7 @@
1153
1215
  }
1154
1216
 
1155
1217
  body {
1156
- @apply bg-prominent text-on-prominent font-sans antialiased;
1218
+ @apply bg-background-primary-canvas text-text-prominent-default font-sans antialiased;
1157
1219
  }
1158
1220
  }
1159
1221
 
@@ -1179,6 +1241,18 @@
1179
1241
  }
1180
1242
 
1181
1243
  /* Skeleton — directional loading sweep (replaces the generic pulse) */
1244
+ /* Slide to Confirm — the confirmed check pops on the overshoot spring */
1245
+ @keyframes slide-confirm-pop {
1246
+ from { transform: scale(0); }
1247
+ to { transform: scale(1); }
1248
+ }
1249
+
1250
+ /* Slide to Confirm — idle nudge on the handle, per the Refined spec */
1251
+ @keyframes slide-confirm-nudge {
1252
+ 0%, 100% { transform: translateX(0); }
1253
+ 50% { transform: translateX(10px); }
1254
+ }
1255
+
1182
1256
  @keyframes skeleton-sweep {
1183
1257
  from { transform: translateX(-100%); }
1184
1258
  to { transform: translateX(100%); }
@@ -1674,6 +1748,94 @@
1674
1748
  font-weight: var(--bottom-navigation-label-font-weight);
1675
1749
  }
1676
1750
 
1751
+ .type-stepper-stake-label {
1752
+ font-family: var(--font-plus-jakarta-sans);
1753
+ font-size: var(--stepper-stake-label-font-size);
1754
+ line-height: var(--stepper-stake-label-line-height);
1755
+ font-weight: var(--stepper-stake-label-font-weight);
1756
+ letter-spacing: 0.08em;
1757
+ text-transform: uppercase;
1758
+ }
1759
+
1760
+ .type-stepper-stake-amount {
1761
+ font-family: var(--font-plus-jakarta-sans);
1762
+ font-size: var(--stepper-stake-amount-font-size);
1763
+ line-height: var(--stepper-stake-amount-line-height);
1764
+ font-weight: var(--stepper-stake-amount-font-weight);
1765
+ font-variant-numeric: tabular-nums;
1766
+ }
1767
+
1768
+ .type-progress-label {
1769
+ font-family: var(--font-plus-jakarta-sans);
1770
+ font-size: var(--progress-label-font-size);
1771
+ line-height: var(--progress-label-line-height);
1772
+ font-weight: var(--progress-label-font-weight);
1773
+ }
1774
+
1775
+ .type-progress-value {
1776
+ font-family: var(--font-plus-jakarta-sans);
1777
+ font-size: var(--progress-value-font-size);
1778
+ line-height: var(--progress-value-line-height);
1779
+ font-weight: var(--progress-value-font-weight);
1780
+ font-variant-numeric: tabular-nums;
1781
+ }
1782
+
1783
+ .type-slide-to-confirm {
1784
+ font-family: var(--font-plus-jakarta-sans);
1785
+ font-size: var(--slide-to-confirm-label-font-size);
1786
+ line-height: var(--slide-to-confirm-label-line-height);
1787
+ font-weight: var(--slide-to-confirm-label-font-weight);
1788
+ }
1789
+
1790
+ /* Confirmed label steps up to semibold via a data-attribute rule —
1791
+ .type-* classes can't be variant-gated. */
1792
+ [data-slot="slide-to-confirm"][data-confirmed] .type-slide-to-confirm {
1793
+ font-weight: var(--slide-to-confirm-label-confirmed-font-weight);
1794
+ }
1795
+
1796
+ .type-steps-indicator {
1797
+ font-family: var(--font-plus-jakarta-sans);
1798
+ font-size: var(--steps-indicator-font-size);
1799
+ line-height: var(--steps-indicator-line-height);
1800
+ font-weight: var(--steps-indicator-font-weight);
1801
+ font-variant-numeric: tabular-nums;
1802
+ }
1803
+
1804
+ .type-steps-title {
1805
+ font-family: var(--font-plus-jakarta-sans);
1806
+ font-size: var(--steps-title-font-size);
1807
+ line-height: var(--steps-title-line-height);
1808
+ font-weight: var(--steps-title-font-weight);
1809
+ }
1810
+
1811
+ .type-steps-description {
1812
+ font-family: var(--font-plus-jakarta-sans);
1813
+ font-size: var(--steps-description-font-size);
1814
+ line-height: var(--steps-description-line-height);
1815
+ font-weight: var(--steps-description-font-weight);
1816
+ }
1817
+
1818
+ .type-steps-tag {
1819
+ font-family: var(--font-plus-jakarta-sans);
1820
+ font-size: var(--steps-tag-font-size);
1821
+ line-height: var(--steps-tag-line-height);
1822
+ font-weight: var(--steps-tag-font-weight);
1823
+ letter-spacing: 0.08em;
1824
+ text-transform: uppercase;
1825
+ }
1826
+
1827
+ /* Steps sm — re-point the private type tokens at the 12/16 primitives */
1828
+ [data-slot="steps"][data-size="sm"] {
1829
+ --steps-indicator-font-size: var(--primitive-font-size-12);
1830
+ --steps-indicator-line-height: var(--primitive-line-height-16);
1831
+ --steps-title-font-size: var(--primitive-font-size-12);
1832
+ --steps-title-line-height: var(--primitive-line-height-16);
1833
+ --steps-description-font-size: var(--primitive-font-size-12);
1834
+ --steps-description-line-height: var(--primitive-line-height-16);
1835
+ }
1836
+
1837
+
1838
+
1677
1839
  /* Bottom Navigation — the arriving icon pops on an overshoot spring; the
1678
1840
  label never moves. */
1679
1841
  [data-slot="bottom-navigation-item"] svg {
@@ -1,77 +0,0 @@
1
- # Toggle Group
2
-
3
- A set of related toggles (Radix ToggleGroup) sharing size/variant, rendered joined by default.
4
-
5
- ## When to use
6
-
7
- - Exclusive or multi-select among a few peer options that stay visible — chart interval (1m/5m/1h), order side, view density.
8
-
9
- **When not:** For switching content panels use [Tabs](./tabs.md). For a single independent control use [Toggle](./toggle.md). For 5+ options use [Select](./select.md).
10
-
11
- ## Anatomy
12
-
13
- - `ToggleGroup` — Radix root; publishes `variant`/`size`/`spacing` through context and sets `--gap`; `data-slot="toggle-group"` with `data-variant`, `data-size`, `data-spacing`.
14
- - `ToggleGroupItem` — one segment, styled by the shared `toggleVariants` from Toggle; `data-slot="toggle-group-item"`, `data-state="on|off"`.
15
-
16
- ## API
17
-
18
- ### ToggleGroup
19
-
20
- | Prop | Type | Default | Notes |
21
- | --- | --- | --- | --- |
22
- | `type` | `"single" \| "multiple"` | — | Radix prop; required. |
23
- | `variant` | `"default" \| "outline"` | — | Inherited by every item via context. |
24
- | `size` | `"default" \| "sm" \| "lg"` | — | Same rail as Toggle (36/32/40px). |
25
- | `spacing` | `number` | `0` | Tailwind spacing units between items; `0` = joined segments. |
26
- | `value` / `defaultValue`, `onValueChange` | Radix props | — | `string` for single, `string[]` for multiple. |
27
-
28
- ### ToggleGroupItem
29
-
30
- | Prop | Type | Default | Notes |
31
- | --- | --- | --- | --- |
32
- | `value` | `string` | — | Required item identity. |
33
- | `variant` / `size` | as Toggle | — | Context wins: group-level values override per-item ones. |
34
-
35
- ## Variants & sizes
36
-
37
- ```tsx
38
- import { ToggleGroup, ToggleGroupItem } from "@trading-game/design-intelligence-layer"
39
-
40
- // joined segments (default)
41
- <ToggleGroup type="single" variant="outline" defaultValue="1h">
42
- <ToggleGroupItem value="1m">1M</ToggleGroupItem>
43
- <ToggleGroupItem value="5m">5M</ToggleGroupItem>
44
- <ToggleGroupItem value="1h">1H</ToggleGroupItem>
45
- </ToggleGroup>
46
-
47
- // spaced multiple-select
48
- <ToggleGroup type="multiple" spacing={2} size="sm">
49
- <ToggleGroupItem value="ema">EMA</ToggleGroupItem>
50
- <ToggleGroupItem value="vol">VOL</ToggleGroupItem>
51
- </ToggleGroup>
52
- ```
53
-
54
- ## Tokens
55
-
56
- **Colour (semantic):** everything from Toggle (`bg-background-hover-default` on-fill/hover, `text-text-brand-selected` on-ink, `border-border-prominent-default` outline), plus `border-border-brand-selected` on an on-segment's border in joined outline groups.
57
- **Type (private):** shared `--toggle-*` family — 14 / medium (500) / 20.
58
-
59
- ## Behaviour
60
-
61
- - `spacing={0}` (default) joins segments: items lose their own radius (`rounded-none`), the first/last regain `rounded-l-md`/`rounded-r-md`, and outline items share borders by dropping `border-l` on all but the first.
62
- - In a joined outline group, an on segment restores its left border and colours its full border `border-border-brand-selected`, so the selected segment reads as outlined in brand.
63
- - Group-level `variant`/`size` override per-item props through context (`context.variant || variant`).
64
- - Items are `w-auto min-w-0 shrink-0 px-3` and raise `z-10` on focus so the ring is never clipped by neighbours.
65
- - Any positive `spacing` separates the items and each keeps its own `rounded-md` shape.
66
-
67
- ## Do / Don't
68
-
69
- **Do**
70
- - Keep the default `spacing={0}` for segmented-control semantics; use spacing only when items act as independent toggles.
71
- - Set `variant`/`size` on the group once; per-item overrides are ignored when the group sets them.
72
- - Use `type="single"` with a `defaultValue` for interval/side pickers so one option is always on.
73
-
74
- **Don't**
75
- - Don't give on-segments a solid brand fill — selection is glaze + `text-brand-selected` ink, with `border-brand-selected` in joined outline groups.
76
- - Don't mix sizes inside one group; the shared border geometry assumes uniform height.
77
- - Don't use a joined group for navigation — that is [Tabs](./tabs.md).