@trading-game/design-intelligence-layer 0.17.1 → 0.17.3

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.
@@ -289,7 +289,7 @@ The system follows a Material-style `<surface>` / `on-<surface>` pair convention
289
289
  | Show WIN / profit / positive | `text-semantic-win` | Primary blue for profit |
290
290
  | Show LOSS / negative | `text-semantic-loss` | Any non-token red |
291
291
  | Show WARNING / caution | `text-semantic-warning` | Raw orange hex or primary tint |
292
- | Show a credit / boost / bonus badge | `<Badge variant="fill-credit">` (uses `bg-semantic-boost-surface` `#FDCA8A` + `text-on-semantic-boost` `#521900`, bold) | Hardcoded amber hex values |
292
+ | Show a credit / boost / bonus badge | `<Badge variant="fill-credit">` (frosted glass — `bg-semantic-boost-surface` = `oklch(1 0 0 / 0.22)` + `backdrop-blur-md` + `text-on-primary`); place it on a coloured surface only — invisible on white | Hardcoded rgba/alpha |
293
293
  | Color a tab container background | `bg-tabs` | `bg-subtle` for tabs |
294
294
  | Color an active/selected tab | `bg-tabs-active` | `bg-prominent` for active tab |
295
295
  | Color a page background | `bg-prominent` | `bg-white` directly |
@@ -416,6 +416,7 @@ The design system uses a custom radius scale (base = 10px). Use these named toke
416
416
  | `secondary` | transparent | `text-on-prominent` | `border-[1.5px] border-border-prominent` | `bg-secondary-hover` | Light surfaces |
417
417
  | `secondary-inverse` | transparent | `text-on-prominent-inverse` | `border-[1.5px] border-primary-inverse` | `bg-primary-inverse/10` | Dark/coloured surfaces |
418
418
  | `tertiary` | transparent | `text-primary` | none | `bg-primary/[0.08]` | Light surfaces |
419
+ | `tertiary-inverse` | transparent | `text-on-primary` | none | `bg-on-primary/[0.10]` | Dark/coloured surfaces |
419
420
 
420
421
  ### 6.2 — Sizes
421
422
 
@@ -546,8 +547,8 @@ import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, Dialog
546
547
  | Field | [complex] | FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSet, FieldContent, FieldTitle, FieldSeparator |
547
548
  | Form | [complex] | FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage |
548
549
  | HoverCard | [composed] | HoverCardTrigger, HoverCardContent |
549
- | Input | [simple] | — |
550
- | InputGroup | [composed] | InputGroupAddon, InputGroupInput, InputGroupButton, InputGroupText, InputGroupTextarea |
550
+ | Input | [simple] | — variants: `default`, `inverse` (dark sunken fill + white text, for use on `bg-primary` and other brand-coloured surfaces). |
551
+ | InputGroup | [composed] | InputGroupAddon, InputGroupInput, InputGroupButton, InputGroupText, InputGroupTextarea. Variants: `default`, `inverse` (propagates to nested controls via context — addon / text / input all swap to the inverse recipe automatically). |
551
552
  | InputOTP | [composed] | InputOTPGroup, InputOTPSlot, InputOTPSeparator. Variants: OTP 4 digits, OTP 6 digits, OTP 6 split, OTP 8 digits, OTP 6 separated |
552
553
  | Item | [composed] | ItemGroup, ItemContent, ItemTitle, ItemDescription, ItemMedia, ItemActions, ItemHeader, ItemFooter, ItemSeparator |
553
554
  | Kbd | [simple] | KbdGroup |
@@ -608,7 +609,7 @@ These are styling behaviors you can't discover from TypeScript types alone:
608
609
  | Menubar | Hover: `bg-primary/[0.08]`. Open state: `bg-primary/10` |
609
610
  | Alert | Dismissible **status** notification. Flat-prop API — pass `title` / `description` / `icon` / `action` / `actions` / `onDismiss` directly; no sub-components. (Promotional / marketing surfaces belong on `Banner`.) **Variants:** `info` (`bg-semantic-info/10`), `warning` (`bg-semantic-warning/10`), `danger` (`bg-semantic-error/10`), `success` (`bg-semantic-win/10`). **Layouts:** `inline` (single row: icon · body · optional action · close X) and `card` (icon · body · close X top-right; up to 2 buttons at bottom-left). **Buttons:** `action` (inline, max 1) and `actions` (card, max 2). Strings get wrapped as `Button variant="secondary" size="sm"`; React elements pass through. **Title colour:** `text-on-prominent` across all variants. **Icon colour:** the variant accent (`text-semantic-info` etc.) carries the severity signal; pass `icon={null}` to omit, or any `ReactNode` to override the per-variant default (`Info`, `AlertTriangle`, `XCircle`, `CheckCircle2`). **Single-line height:** `min-h-12` (48px floor) when only `title` or only `description` is provided in inline layout; grows when content wraps on narrow viewports. **Dismiss:** controlled — `onDismiss` callback; parent owns visibility. **A11y:** `role="alert"` + `aria-live="assertive"` for `danger`/`warning`; `role="status"` + `aria-live="polite"` for `info`/`success`. |
610
611
  | Banner | Dismissible **promotional / marketing** surface — feature launches, offers, onboarding nudges, cross-promo. Single visual treatment (no severity variants); for status messages use `Alert`. Flat-prop API: `layout`, `title`, `description`, `icon`/`glyph`, `action`, `actions`, `onDismiss`, `dismissLabel`, `onClick`. **Surface:** tinted primary surface (`bg-primary/[0.08]`) with `border-primary/[0.16]` edge, `rounded-sm` (6 px — matches Card / Alert), `px-4 py-3.5`. **Layouts:** `inline` (icon · body · optional action · close X, single row) and `card` (body row + actions row beneath, bottom-left, max 2 buttons). When the body is multi-line (description set, or `layout="card"`), the grid switches to `items-start` so the leading icon top-aligns with the title; single-line banners stay `items-center`. Multi-line banners also pin the close X to `absolute top-3 right-3` and apply `pr-12` to the surface so the body never wraps under the corner. **Buttons:** strings get wrapped in `Button variant="secondary" size="sm"` across every slot (inline `action` and card `actions`). React elements pass through unchanged. **Title:** `text-sm font-bold text-on-prominent`; wrap emphasis in `<b>` for an in-line brand-blue accent (`[&>b]:text-primary`). **Description:** `text-xs font-medium text-on-subtle`, `mt-0.5` from title. **Default icon:** built-in 40 px brand-blue **square** (`rounded-xs bg-primary`, 4 px corners) with a white `Gift` glyph inside. Two ways to customise: `glyph` swaps just the inner icon while keeping the brand-badge shell intact (use this for "different symbol, same brand badge"); `icon` replaces the entire wrapper (use for fully custom artwork). `icon={null}` omits the column. `icon` wins if both are set — a dev warning fires. **`onClick`:** when set, the whole surface becomes the CTA (cursor-pointer, hover/focus states, keyboard activation). Mutually exclusive with `action`/`actions` — buttons are silently dropped and a dev warning fires. Close X stops propagation so dismissing never triggers the surface click. **A11y:** no `role`/`aria-live` (Banner is not a status surface). |
611
- | Badge | Variants: `default` (solid blue), `default-success`, `default-fail`, `default-warning` (all use `bg-semantic-*` + matching `text-on-semantic-*` foreground); `fill` (blue tint), `fill-success`, `fill-fail`, `fill-warning`; `fill-credit` (light-peach solid `bg-semantic-boost-surface` + `text-on-semantic-boost` foreground — use for credit/bonus labels); `fill-demo` (red-orange tint — `bg-semantic-demo/10` + `text-semantic-demo` — dedicated to "demo account" / "test mode" flags, **not** a severity signal); `outline`; `ghost`, `ghost-success`, `ghost-fail`. Base class no longer applies `tracking-wide` — letter spacing is default. |
612
+ | Badge | Variants: `default` (solid blue), `default-success`, `default-fail`, `default-warning` (all use `bg-semantic-*` + matching `text-on-semantic-*` foreground); `fill` (blue tint), `fill-success`, `fill-fail`, `fill-warning`; `fill-credit` (**frosted-glass chip** — `bg-semantic-boost-surface` = `oklch(1 0 0 / 0.22)` translucent white + `backdrop-blur-md` + `text-on-primary` white text; readable only on coloured surfaces — designed to overlay a brand-blue hero card / wallet card, matching the wallet mock's `.c-hero-wc`); `fill-demo` (red-orange tint — `bg-semantic-demo/10` + `text-semantic-demo` — dedicated to "demo account" / "test mode" flags, **not** a severity signal); `outline`; `ghost`, `ghost-success`, `ghost-fail`. Base class no longer applies `tracking-wide` — letter spacing is default. |
612
613
  | TicketCard | **Icon:** pass any `ReactNode` via `icon`. Icon container: `size-10` rounded-full, `border-2 border-primary`, `text-primary`. **Labels:** `label` (above value) and `stubLabel` (stub button) render in sentence case — do NOT apply `uppercase` or `tracking-widest`. Stub: `w-[100px]` `bg-primary` button, `text-on-primary`, shimmer sweep animation. Disabled stub: `opacity-50`, `cursor-not-allowed`. Perforation notches sit outside the card box — do NOT put `overflow-hidden` on the card wrapper. **`compact`** (default `false`): `true` = mobile layout — reduces left-content horizontal padding from `px-4 gap-4` to `px-2 gap-2`. **For Welcome credit / bonus use cases:** use `CreditTicketCard` instead — it renders a `<Badge variant="fill-credit">` next to (or below, on narrow compact widths) the value. |
613
614
  | CreditTicketCard | Same visual shell as `TicketCard` (perforation notches, tear-line, shimmer stub). The card height is **variable** (grows with content via `py-4`) rather than fixed at `h-20`. The credit is displayed as an inline `<Badge variant="fill-credit" size="sm">` formatted as *"{badgeValue} {badgeCurrency}"* (e.g. `10.00 USDT`). The badge composes optional `badgeIcon` (e.g. `<Gift />`) on the left and an info trigger on the right that opens `badgeInfo` (desktop: `Tooltip variant="inverse"`; mobile: `Drawer`). Tokens used: `bg-subtle`, `bg-primary`, `bg-primary-hover`, `text-on-primary`, `bg-semantic-boost-surface` (`#FDCA8A`), `text-on-semantic-boost` (`#521900`, bold). `compact` shrinks padding and lets the badge wrap to a second line under the value only when balance + badge would otherwise overflow into the deposit stub (responsive `flex-wrap`). |
614
615
  | Toggle | Pressed: `bg-primary/10` + `border-primary` + `text-primary` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trading-game/design-intelligence-layer",
3
- "version": "0.17.1",
3
+ "version": "0.17.3",
4
4
  "description": "Trading Game Design System — shadcn/ui components with Tailwind CSS v4",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
package/src/styles.css CHANGED
@@ -40,6 +40,7 @@
40
40
  --color-sidebar: var(--sidebar);
41
41
  --color-ring: var(--ring);
42
42
  --color-input: var(--input);
43
+ --color-input-inverse-surface: var(--input-inverse-surface);
43
44
  --color-border: var(--border);
44
45
  /* @deprecated — use border-border-subtle or border-border-prominent */
45
46
  --color-border-subtle: var(--border-subtle);
@@ -313,8 +314,11 @@
313
314
  looks the same on any background (mirrors --semantic-boost-surface for credit) */
314
315
  --semantic-boost: var(--primitive-amber-600);
315
316
  /* #F9840F — boost badge surface */
316
- --semantic-boost-surface: var(--primitive-amber-300);
317
- /* #FDCA8A — solid tinted surface for credit/boost badges on any background */
317
+ --semantic-boost-surface: oklch(1 0 0 / 0.22);
318
+ /* Frosted glass surface for credit/boost badges — translucent white that
319
+ composes over whatever surface sits behind it (typically a coloured
320
+ hero card). Pair with backdrop-blur and `text-on-primary` for the
321
+ classic glass-chip look. */
318
322
  --on-semantic-boost: var(--primitive-amber-900);
319
323
  /* #521900 — text/icon color for use on semantic-boost surfaces */
320
324
  --tabs: var(--primitive-mono-alpha-4);
@@ -390,6 +394,11 @@
390
394
  --popover: var(--primitive-mono-50);
391
395
  --popover-foreground: oklch(0.07 0.012 165);
392
396
  --input: var(--border-subtle);
397
+ /* Sunken dark fill for Input/InputGroup variant="inverse" — sits on
398
+ coloured surfaces (brand-blue, etc.) where a frosted-white fill would
399
+ blend into the surrounding chrome. 35 % black overlay deepens the
400
+ surface enough for white text to read cleanly. */
401
+ --input-inverse-surface: oklch(0 0 0 / 0.35);
393
402
  --alert-info-text: var(--semantic-info);
394
403
  --alert-info-border: var(--semantic-info);
395
404
  --alert-error-text: var(--semantic-error);
@@ -422,6 +431,21 @@
422
431
  100% { transform: translateX(100%); }
423
432
  }
424
433
 
434
+ /* Button shimmer — two quick back-to-back sweeps, then a ~3s pause.
435
+ At a 4s cycle: sweep 1 over 0%–12% (~480ms), an invisible reset
436
+ between 12%–13.5% (opacity-fade so no back-sweep is visible),
437
+ sweep 2 over 13.5%–25%, then the bright band parks off-right for
438
+ the remaining ~75% of the cycle. */
439
+ @keyframes button-shimmer {
440
+ 0% { transform: translateX(-100%); opacity: 1; }
441
+ 12% { transform: translateX(100%); opacity: 1; }
442
+ 12.5% { opacity: 0; }
443
+ 13% { transform: translateX(-100%); opacity: 0; }
444
+ 13.5% { opacity: 1; }
445
+ 25% { transform: translateX(100%); opacity: 1; }
446
+ 100% { transform: translateX(100%); opacity: 1; }
447
+ }
448
+
425
449
  /* Spinner — pill-style activity indicator */
426
450
  @keyframes spinner-fade {
427
451
  0% {