@trading-game/design-intelligence-layer 1.0.5 → 1.0.6

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/dist/index.d.cts CHANGED
@@ -337,7 +337,22 @@ declare function DrawerTrigger({ ...props }: React$1.ComponentProps<typeof Drawe
337
337
  declare function DrawerPortal({ ...props }: React$1.ComponentProps<typeof Drawer$1.Portal>): react_jsx_runtime.JSX.Element;
338
338
  declare function DrawerClose({ ...props }: React$1.ComponentProps<typeof Drawer$1.Close>): react_jsx_runtime.JSX.Element;
339
339
  declare function DrawerOverlay({ className, ...props }: React$1.ComponentProps<typeof Drawer$1.Overlay>): react_jsx_runtime.JSX.Element;
340
- declare function DrawerContent({ className, children, ...props }: React$1.ComponentProps<typeof Drawer$1.Content>): react_jsx_runtime.JSX.Element;
340
+ declare function DrawerContent({ className, children, dismiss, ...props }: React$1.ComponentProps<typeof Drawer$1.Content> & {
341
+ /**
342
+ * How the drawer offers to close.
343
+ *
344
+ * `"handle"` (default, unchanged) is the drag pill, shown only on the
345
+ * bottom direction. `"close"` swaps it for the same control Dialog and
346
+ * Sheet use — `NavigationButton size="sm"` around a `size-4` icon, a 32px
347
+ * circle on a 16px glyph — and shows it in every direction.
348
+ *
349
+ * The button sits in flow on its own row, not absolutely positioned, so
350
+ * nothing shares its line and the header always starts below it. `p-4 pb-0`
351
+ * puts it 16px from the top and right edges, matching the header's own
352
+ * padding.
353
+ */
354
+ dismiss?: "handle" | "close";
355
+ }): react_jsx_runtime.JSX.Element;
341
356
  declare function DrawerHeader({ className, ...props }: React$1.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
342
357
  declare function DrawerFooter({ className, ...props }: React$1.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
343
358
  declare function DrawerTitle({ className, ...props }: React$1.ComponentProps<typeof Drawer$1.Title>): react_jsx_runtime.JSX.Element;
@@ -1117,7 +1132,7 @@ interface GameLoadingBlockProps {
1117
1132
  label?: string;
1118
1133
  /** When true, swaps the label for a "taking longer" message. */
1119
1134
  delayed?: boolean;
1120
- /** Plays the zoom-out reveal and hides the bar. */
1135
+ /** Plays the reveal and hides the bar. */
1121
1136
  exiting?: boolean;
1122
1137
  /** Fires once the exit animation finishes. */
1123
1138
  onExitEnd?: () => void;
@@ -1128,20 +1143,35 @@ interface GameLoadingBlockProps {
1128
1143
  */
1129
1144
  contained?: boolean;
1130
1145
  /**
1131
- * Optional backdrop image (e.g. the app's `dot-pattern.webp`) for a
1132
- * pixel-perfect match with the game shell. Omit to use the token-derived
1133
- * dotted backdrop.
1146
+ * The product mark, as a URL to a transparent PNG or SVG. This block ships
1147
+ * in the package, so it cannot reach into a consuming app's asset folder —
1148
+ * pass the theme-matched file (`chmp-trd-logo-brand-light.png` in light,
1149
+ * `…-dark.png` in dark). The same URL draws the resting mark *and* cuts the
1150
+ * hole the reveal grows, so both always agree. Omit it and the reveal
1151
+ * degrades to a plain fade with no mark.
1152
+ */
1153
+ logoSrc?: string;
1154
+ /**
1155
+ * Optional backdrop image for a pixel-perfect match with the game shell.
1156
+ * Replaces the token-derived tinted canvas; the mark is still knocked out
1157
+ * of it, so the reveal works either way.
1134
1158
  */
1135
1159
  backgroundImageUrl?: string;
1136
1160
  className?: string;
1137
1161
  }
1138
1162
  /**
1139
- * Determinate loading splash for game entry: dotted brand backdrop, monogram,
1140
- * and a progress bar with a shimmer that keeps signalling life while a stage
1141
- * is held. Exits with a zoom-out reveal, or a plain fade under
1142
- * `prefers-reduced-motion`.
1163
+ * Determinate loading splash for game entry: the tinted-canvas backdrop, the
1164
+ * product mark, and a progress bar whose shimmer keeps signalling life while a
1165
+ * stage is held.
1166
+ *
1167
+ * The exit is a knock-out reveal. The mark is cut out of the backdrop as a
1168
+ * hole, and only that hole grows — the backdrop itself never moves, so its
1169
+ * gradient and dot grid stay put instead of appearing to zoom. The backdrop
1170
+ * fades across the same beat, so the app bleeds through from about a third of
1171
+ * the way in rather than arriving all at once. Under
1172
+ * `prefers-reduced-motion` the whole thing is a plain fade.
1143
1173
  */
1144
- declare function GameLoadingBlock({ progress, label, delayed, exiting, onExitEnd, contained, backgroundImageUrl, className, }: GameLoadingBlockProps): react_jsx_runtime.JSX.Element;
1174
+ declare function GameLoadingBlock({ progress, label, delayed, exiting, onExitEnd, contained, logoSrc, backgroundImageUrl, className, }: GameLoadingBlockProps): react_jsx_runtime.JSX.Element;
1145
1175
 
1146
1176
  declare function cn(...inputs: ClassValue[]): string;
1147
1177
 
package/dist/index.d.ts CHANGED
@@ -337,7 +337,22 @@ declare function DrawerTrigger({ ...props }: React$1.ComponentProps<typeof Drawe
337
337
  declare function DrawerPortal({ ...props }: React$1.ComponentProps<typeof Drawer$1.Portal>): react_jsx_runtime.JSX.Element;
338
338
  declare function DrawerClose({ ...props }: React$1.ComponentProps<typeof Drawer$1.Close>): react_jsx_runtime.JSX.Element;
339
339
  declare function DrawerOverlay({ className, ...props }: React$1.ComponentProps<typeof Drawer$1.Overlay>): react_jsx_runtime.JSX.Element;
340
- declare function DrawerContent({ className, children, ...props }: React$1.ComponentProps<typeof Drawer$1.Content>): react_jsx_runtime.JSX.Element;
340
+ declare function DrawerContent({ className, children, dismiss, ...props }: React$1.ComponentProps<typeof Drawer$1.Content> & {
341
+ /**
342
+ * How the drawer offers to close.
343
+ *
344
+ * `"handle"` (default, unchanged) is the drag pill, shown only on the
345
+ * bottom direction. `"close"` swaps it for the same control Dialog and
346
+ * Sheet use — `NavigationButton size="sm"` around a `size-4` icon, a 32px
347
+ * circle on a 16px glyph — and shows it in every direction.
348
+ *
349
+ * The button sits in flow on its own row, not absolutely positioned, so
350
+ * nothing shares its line and the header always starts below it. `p-4 pb-0`
351
+ * puts it 16px from the top and right edges, matching the header's own
352
+ * padding.
353
+ */
354
+ dismiss?: "handle" | "close";
355
+ }): react_jsx_runtime.JSX.Element;
341
356
  declare function DrawerHeader({ className, ...props }: React$1.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
342
357
  declare function DrawerFooter({ className, ...props }: React$1.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
343
358
  declare function DrawerTitle({ className, ...props }: React$1.ComponentProps<typeof Drawer$1.Title>): react_jsx_runtime.JSX.Element;
@@ -1117,7 +1132,7 @@ interface GameLoadingBlockProps {
1117
1132
  label?: string;
1118
1133
  /** When true, swaps the label for a "taking longer" message. */
1119
1134
  delayed?: boolean;
1120
- /** Plays the zoom-out reveal and hides the bar. */
1135
+ /** Plays the reveal and hides the bar. */
1121
1136
  exiting?: boolean;
1122
1137
  /** Fires once the exit animation finishes. */
1123
1138
  onExitEnd?: () => void;
@@ -1128,20 +1143,35 @@ interface GameLoadingBlockProps {
1128
1143
  */
1129
1144
  contained?: boolean;
1130
1145
  /**
1131
- * Optional backdrop image (e.g. the app's `dot-pattern.webp`) for a
1132
- * pixel-perfect match with the game shell. Omit to use the token-derived
1133
- * dotted backdrop.
1146
+ * The product mark, as a URL to a transparent PNG or SVG. This block ships
1147
+ * in the package, so it cannot reach into a consuming app's asset folder —
1148
+ * pass the theme-matched file (`chmp-trd-logo-brand-light.png` in light,
1149
+ * `…-dark.png` in dark). The same URL draws the resting mark *and* cuts the
1150
+ * hole the reveal grows, so both always agree. Omit it and the reveal
1151
+ * degrades to a plain fade with no mark.
1152
+ */
1153
+ logoSrc?: string;
1154
+ /**
1155
+ * Optional backdrop image for a pixel-perfect match with the game shell.
1156
+ * Replaces the token-derived tinted canvas; the mark is still knocked out
1157
+ * of it, so the reveal works either way.
1134
1158
  */
1135
1159
  backgroundImageUrl?: string;
1136
1160
  className?: string;
1137
1161
  }
1138
1162
  /**
1139
- * Determinate loading splash for game entry: dotted brand backdrop, monogram,
1140
- * and a progress bar with a shimmer that keeps signalling life while a stage
1141
- * is held. Exits with a zoom-out reveal, or a plain fade under
1142
- * `prefers-reduced-motion`.
1163
+ * Determinate loading splash for game entry: the tinted-canvas backdrop, the
1164
+ * product mark, and a progress bar whose shimmer keeps signalling life while a
1165
+ * stage is held.
1166
+ *
1167
+ * The exit is a knock-out reveal. The mark is cut out of the backdrop as a
1168
+ * hole, and only that hole grows — the backdrop itself never moves, so its
1169
+ * gradient and dot grid stay put instead of appearing to zoom. The backdrop
1170
+ * fades across the same beat, so the app bleeds through from about a third of
1171
+ * the way in rather than arriving all at once. Under
1172
+ * `prefers-reduced-motion` the whole thing is a plain fade.
1143
1173
  */
1144
- declare function GameLoadingBlock({ progress, label, delayed, exiting, onExitEnd, contained, backgroundImageUrl, className, }: GameLoadingBlockProps): react_jsx_runtime.JSX.Element;
1174
+ declare function GameLoadingBlock({ progress, label, delayed, exiting, onExitEnd, contained, logoSrc, backgroundImageUrl, className, }: GameLoadingBlockProps): react_jsx_runtime.JSX.Element;
1145
1175
 
1146
1176
  declare function cn(...inputs: ClassValue[]): string;
1147
1177
 
package/dist/index.js CHANGED
@@ -162,7 +162,7 @@ var buttonVariants = cva(
162
162
  variants: {
163
163
  variant: {
164
164
  // Primary brand blue (#2323FF)
165
- primary: "bg-background-brand-default text-text-on-brand-static hover:bg-background-brand-hover active:bg-background-brand-pressed active:opacity-100 disabled:[background-image:linear-gradient(var(--background-disabled-default),var(--background-disabled-default))] disabled:text-text-disabled-default",
165
+ primary: "bg-background-brand-default text-text-on-brand-static hover:bg-background-brand-hover active:bg-background-brand-pressed active:opacity-100 disabled:opacity-(--opacity-disabled)",
166
166
  // Primary Inverse — white bg + blue text; for use on dark/coloured surfaces
167
167
  // On-brand family — for buttons standing on a brand-coloured surface
168
168
  // (NOT theme inverses): white pill with primary ink, white outline,
@@ -181,7 +181,7 @@ var buttonVariants = cva(
181
181
  // (white-alpha-32 = 1.84:1 on brand, against 1.71:1 here) so both
182
182
  // read as the same quiet edge. Its contrast is higher only because it
183
183
  // has no fill behind it — there, the border IS the button.
184
- secondary: "bg-background-primary-surface border-[1.5px] border-border-control-default text-text-prominent-default hover:bg-background-secondary-surface disabled:[background-image:linear-gradient(var(--background-disabled-default),var(--background-disabled-default))] disabled:border-border-disabled-default disabled:text-text-disabled-default",
184
+ secondary: "button-disabled-secondary bg-background-primary-surface border-[1.5px] border-border-control-default text-text-prominent-default hover:bg-background-secondary-surface",
185
185
  // Secondary Inverse — white border + white text; for use on dark/coloured surfaces
186
186
  "secondary-on-brand": "bg-transparent border-[1.5px] border-(--primitive-white-alpha-32) text-text-on-brand-static hover:bg-(--primitive-white-alpha-8) disabled:border-(--primitive-white-alpha-16) disabled:text-text-on-brand-disabled-default",
187
187
  tertiary: "bg-transparent text-text-prominent-default hover:bg-background-hover-default disabled:text-text-disabled-default",
@@ -192,7 +192,7 @@ var buttonVariants = cva(
192
192
  // hover/pressed via the state-layer glazes stacked over the solid
193
193
  // fill); `frosted-on-brand` is the white frost for coloured/art
194
194
  // surfaces (hover thickens the frost, press thins it).
195
- frosted: "bg-background-brand-selected text-text-brand-selected active:opacity-100 hover:[background-image:linear-gradient(var(--background-hover-default),var(--background-hover-default))] active:[background-image:linear-gradient(var(--background-pressed-default),var(--background-pressed-default))] disabled:[background-image:linear-gradient(var(--background-disabled-default),var(--background-disabled-default))] disabled:text-text-disabled-default",
195
+ frosted: "bg-background-brand-selected text-text-brand-selected active:opacity-100 hover:[background-image:linear-gradient(var(--background-hover-default),var(--background-hover-default))] active:[background-image:linear-gradient(var(--background-pressed-default),var(--background-pressed-default))] disabled:opacity-(--opacity-disabled-frosted)",
196
196
  "frosted-on-brand": "bg-(--primitive-white-alpha-24) backdrop-blur-md text-text-on-brand-static hover:bg-(--primitive-white-alpha-32) active:bg-(--primitive-white-alpha-16) active:opacity-100 disabled:bg-(--primitive-white-alpha-8) disabled:text-text-on-brand-disabled-default",
197
197
  /* @deprecated aliases — shimmer became the `shimmer` boolean prop;
198
198
  the inverse names became the on-brand family; `glass` became
@@ -2465,7 +2465,7 @@ function Checkbox(_a) {
2465
2465
  __spreadProps(__spreadValues({
2466
2466
  "data-slot": "checkbox",
2467
2467
  className: cn(
2468
- "peer size-4 shrink-0 rounded-2xs border border-border-default-default bg-background-primary-surface transition-colors outline-none focus-visible:border-ring-focus-default focus-visible:ring-[3px] focus-visible:ring-ring-focus-strong disabled:cursor-not-allowed disabled:border-border-default-default disabled:text-text-disabled-default data-[state=checked]:border-transparent data-[state=checked]:bg-background-brand-default data-[state=checked]:text-text-on-brand-static",
2468
+ "peer size-4 shrink-0 rounded-2xs border border-border-default-default bg-background-primary-surface transition-colors outline-none focus-visible:border-ring-focus-default focus-visible:ring-[3px] focus-visible:ring-ring-focus-strong disabled:cursor-not-allowed disabled:opacity-(--opacity-disabled) data-[state=checked]:border-transparent data-[state=checked]:bg-background-brand-default data-[state=checked]:text-text-on-brand-static",
2469
2469
  className
2470
2470
  )
2471
2471
  }, props), {
@@ -3014,6 +3014,7 @@ function ContextMenuShortcut(_a) {
3014
3014
  }
3015
3015
 
3016
3016
  // components/ui/drawer.tsx
3017
+ import { XIcon as XIcon2 } from "lucide-react";
3017
3018
  import { Drawer as DrawerPrimitive } from "vaul";
3018
3019
  import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
3019
3020
  function Drawer(_a) {
@@ -3052,10 +3053,12 @@ function DrawerOverlay(_a) {
3052
3053
  function DrawerContent(_a) {
3053
3054
  var _b = _a, {
3054
3055
  className,
3055
- children
3056
+ children,
3057
+ dismiss = "handle"
3056
3058
  } = _b, props = __objRest(_b, [
3057
3059
  "className",
3058
- "children"
3060
+ "children",
3061
+ "dismiss"
3059
3062
  ]);
3060
3063
  return /* @__PURE__ */ jsxs15(DrawerPortal, { "data-slot": "drawer-portal", children: [
3061
3064
  /* @__PURE__ */ jsx23(DrawerOverlay, {}),
@@ -3073,7 +3076,15 @@ function DrawerContent(_a) {
3073
3076
  )
3074
3077
  }, props), {
3075
3078
  children: [
3076
- /* @__PURE__ */ jsx23("div", { className: "mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full bg-border-default-default group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }),
3079
+ dismiss === "handle" ? /* @__PURE__ */ jsx23("div", { className: "mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full bg-border-default-default group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }) : /* @__PURE__ */ jsx23("div", { className: "flex shrink-0 justify-end p-4 pb-0", children: /* @__PURE__ */ jsx23(DrawerPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx23(
3080
+ NavigationButton,
3081
+ {
3082
+ "data-slot": "drawer-close",
3083
+ size: "sm",
3084
+ "aria-label": "Close",
3085
+ children: /* @__PURE__ */ jsx23(XIcon2, { className: "size-4" })
3086
+ }
3087
+ ) }) }),
3077
3088
  children
3078
3089
  ]
3079
3090
  })
@@ -4761,7 +4772,7 @@ function NativeSelect(_a) {
4761
4772
  "data-slot": "native-select",
4762
4773
  "data-size": resolvedSize,
4763
4774
  className: cn(
4764
- "w-full min-w-0 appearance-none rounded-xs border border-border-default-default bg-background-primary-surface px-3 pr-9 text-text-prominent-default transition-[color,box-shadow] outline-none selection:bg-background-brand-default selection:text-text-on-brand-static disabled:pointer-events-none disabled:cursor-not-allowed disabled:[background-image:linear-gradient(var(--background-disabled-default),var(--background-disabled-default))]",
4775
+ "w-full min-w-0 appearance-none rounded-xs border border-border-default-default bg-background-primary-surface px-3 pr-9 text-text-prominent-default transition-[color,box-shadow] outline-none disabled:text-text-disabled-default selection:bg-background-brand-default selection:text-text-on-brand-static disabled:pointer-events-none disabled:cursor-not-allowed disabled:[background-image:linear-gradient(var(--background-disabled-default),var(--background-disabled-default))]",
4765
4776
  "focus-visible:border-ring-focus-default focus-visible:ring-[3px] focus-visible:ring-ring-focus-soft",
4766
4777
  sizeClasses[resolvedSize],
4767
4778
  className
@@ -4771,7 +4782,7 @@ function NativeSelect(_a) {
4771
4782
  /* @__PURE__ */ jsx37(
4772
4783
  ChevronDownIcon4,
4773
4784
  {
4774
- className: "pointer-events-none absolute top-1/2 right-3.5 size-4 -translate-y-1/2 text-icon-subtle-default select-none",
4785
+ className: "pointer-events-none absolute top-1/2 right-3.5 size-4 -translate-y-1/2 text-icon-subtle-default select-none group-has-[select:disabled]/native-select:text-icon-disabled-default",
4775
4786
  "aria-hidden": "true",
4776
4787
  "data-slot": "native-select-icon"
4777
4788
  }
@@ -5483,7 +5494,7 @@ function RadioGroupItem(_a) {
5483
5494
  __spreadProps(__spreadValues({
5484
5495
  "data-slot": "radio-group-item",
5485
5496
  className: cn(
5486
- "aspect-square size-4 shrink-0 rounded-full border border-border-default-default bg-background-primary-surface transition-[color,box-shadow] outline-none focus-visible:border-ring-focus-default focus-visible:ring-[3px] focus-visible:ring-ring-focus-strong data-[state=checked]:border-border-brand-selected disabled:cursor-not-allowed disabled:border-border-default-default disabled:text-text-disabled-default aria-invalid:border-border-error-default aria-invalid:ring-ring-error-soft",
5497
+ "aspect-square size-4 shrink-0 rounded-full border border-border-default-default bg-background-primary-surface transition-[color,box-shadow] outline-none focus-visible:border-ring-focus-default focus-visible:ring-[3px] focus-visible:ring-ring-focus-strong data-[state=checked]:border-border-brand-selected disabled:cursor-not-allowed disabled:opacity-(--opacity-disabled) aria-invalid:border-border-error-default aria-invalid:ring-ring-error-soft",
5487
5498
  className
5488
5499
  )
5489
5500
  }, props), {
@@ -5610,7 +5621,7 @@ function ScrollBar(_a) {
5610
5621
  }
5611
5622
 
5612
5623
  // components/ui/sheet.tsx
5613
- import { XIcon as XIcon2 } from "lucide-react";
5624
+ import { XIcon as XIcon3 } from "lucide-react";
5614
5625
  import { Dialog as SheetPrimitive } from "radix-ui";
5615
5626
  import { jsx as jsx46, jsxs as jsxs25 } from "react/jsx-runtime";
5616
5627
  function Sheet(_a) {
@@ -5682,7 +5693,7 @@ function SheetContent(_a) {
5682
5693
  size: "sm",
5683
5694
  "aria-label": "Close",
5684
5695
  className: "absolute top-4 right-4",
5685
- children: /* @__PURE__ */ jsx46(XIcon2, { className: "size-4" })
5696
+ children: /* @__PURE__ */ jsx46(XIcon3, { className: "size-4" })
5686
5697
  }
5687
5698
  ) })
5688
5699
  ]
@@ -7072,7 +7083,11 @@ function Stepper({
7072
7083
  "data-slot": "stepper",
7073
7084
  "data-disabled": disabled || void 0,
7074
7085
  className: cn(
7075
- "flex w-full items-center justify-between gap-4",
7086
+ // Two rows: the label spans the control, then the -/value/+ row sits
7087
+ // under it with a 4px gap. The label is deliberately NOT inside the
7088
+ // value column — nesting it there makes the buttons centre against the
7089
+ // label+value stack, which drops them below the number.
7090
+ "flex w-full flex-col gap-1",
7076
7091
  // No opacity here on purpose. The +/- are Buttons and already carry
7077
7092
  // their own disabled treatment; dimming the wrapper too multiplied
7078
7093
  // with theirs (24% × 24% ≈ 6%) and made them all but invisible.
@@ -7081,63 +7096,72 @@ function Stepper({
7081
7096
  className
7082
7097
  ),
7083
7098
  children: [
7084
- /* @__PURE__ */ jsx53(
7085
- Button,
7099
+ label != null && /* @__PURE__ */ jsx53(
7100
+ "span",
7086
7101
  {
7087
- type: "button",
7088
- variant: "frosted",
7089
- size: "icon-lg",
7090
- onClick: handleDecrement,
7091
- disabled: disabled || currentValue <= min,
7092
- "aria-label": "Decrease value",
7093
- children: /* @__PURE__ */ jsx53(Minus, {})
7102
+ "data-slot": "stepper-label",
7103
+ className: cn(
7104
+ "type-stepper-stake-label text-center",
7105
+ disabled ? "text-text-disabled-default" : "text-text-subtle-default"
7106
+ ),
7107
+ children: label
7094
7108
  }
7095
7109
  ),
7096
- /* @__PURE__ */ jsxs31("div", { className: "flex min-w-0 flex-col items-center", children: [
7097
- label != null && /* @__PURE__ */ jsx53(
7098
- "span",
7099
- {
7100
- className: cn(
7101
- "type-stepper-stake-label",
7102
- disabled ? "text-text-disabled-default" : "text-text-subtle-default"
7103
- ),
7104
- children: label
7105
- }
7106
- ),
7107
- /* @__PURE__ */ jsx53(
7108
- "input",
7109
- {
7110
- type: "text",
7111
- inputMode: "decimal",
7112
- role: "spinbutton",
7113
- "aria-valuemin": min === -Infinity ? void 0 : min,
7114
- "aria-valuemax": max === Infinity ? void 0 : max,
7115
- "aria-valuenow": currentValue,
7116
- "aria-label": ariaLabel,
7117
- value: displayString,
7118
- onChange: handleInputChange,
7119
- onBlur: handleBlur,
7120
- onFocus: handleFocus,
7121
- onKeyDown: handleKeyDown,
7122
- disabled,
7123
- placeholder,
7124
- id,
7125
- name,
7126
- size: Math.max(displayString.length, 1),
7127
- className: "type-stepper-stake-amount w-full min-w-0 border-0 bg-transparent text-center text-text-prominent-default outline-none disabled:text-text-disabled-default [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
7128
- }
7129
- )
7130
- ] }),
7131
- /* @__PURE__ */ jsx53(
7132
- Button,
7110
+ /* @__PURE__ */ jsxs31(
7111
+ "div",
7133
7112
  {
7134
- type: "button",
7135
- variant: "frosted",
7136
- size: "icon-lg",
7137
- onClick: handleIncrement,
7138
- disabled: disabled || currentValue >= max,
7139
- "aria-label": "Increase value",
7140
- children: /* @__PURE__ */ jsx53(Plus, {})
7113
+ "data-slot": "stepper-row",
7114
+ className: "flex w-full items-center justify-between gap-4",
7115
+ children: [
7116
+ /* @__PURE__ */ jsx53(
7117
+ Button,
7118
+ {
7119
+ type: "button",
7120
+ variant: "frosted",
7121
+ size: "icon-lg",
7122
+ onClick: handleDecrement,
7123
+ disabled: disabled || currentValue <= min,
7124
+ "aria-label": "Decrease value",
7125
+ children: /* @__PURE__ */ jsx53(Minus, {})
7126
+ }
7127
+ ),
7128
+ /* @__PURE__ */ jsx53(
7129
+ "input",
7130
+ {
7131
+ type: "text",
7132
+ inputMode: "decimal",
7133
+ role: "spinbutton",
7134
+ "aria-valuemin": min === -Infinity ? void 0 : min,
7135
+ "aria-valuemax": max === Infinity ? void 0 : max,
7136
+ "aria-valuenow": currentValue,
7137
+ "aria-label": ariaLabel,
7138
+ value: displayString,
7139
+ onChange: handleInputChange,
7140
+ onBlur: handleBlur,
7141
+ onFocus: handleFocus,
7142
+ onKeyDown: handleKeyDown,
7143
+ disabled,
7144
+ placeholder,
7145
+ id,
7146
+ name,
7147
+ size: Math.max(displayString.length, 1),
7148
+ "data-slot": "stepper-value",
7149
+ className: "type-stepper-stake-amount min-w-0 flex-1 border-0 bg-transparent text-center text-text-prominent-default outline-none disabled:text-text-disabled-default [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
7150
+ }
7151
+ ),
7152
+ /* @__PURE__ */ jsx53(
7153
+ Button,
7154
+ {
7155
+ type: "button",
7156
+ variant: "frosted",
7157
+ size: "icon-lg",
7158
+ onClick: handleIncrement,
7159
+ disabled: disabled || currentValue >= max,
7160
+ "aria-label": "Increase value",
7161
+ children: /* @__PURE__ */ jsx53(Plus, {})
7162
+ }
7163
+ )
7164
+ ]
7141
7165
  }
7142
7166
  )
7143
7167
  ]
@@ -7367,7 +7391,7 @@ function Switch(_a) {
7367
7391
  "data-slot": "switch",
7368
7392
  "data-size": size,
7369
7393
  className: cn(
7370
- "peer group/switch inline-flex shrink-0 items-center rounded-full border border-transparent p-[3px] transition-all outline-none focus-visible:border-ring-focus-default focus-visible:ring-[3px] focus-visible:ring-ring-focus-strong disabled:cursor-not-allowed disabled:border-border-default-default disabled:text-text-disabled-default data-[size=default]:h-6 data-[size=default]:w-11 data-[size=sm]:h-5 data-[size=sm]:w-9 data-[state=checked]:bg-background-brand-default data-[state=unchecked]:bg-border-default-default",
7394
+ "peer group/switch inline-flex shrink-0 items-center rounded-full border border-transparent p-[3px] transition-all outline-none focus-visible:border-ring-focus-default focus-visible:ring-[3px] focus-visible:ring-ring-focus-strong disabled:cursor-not-allowed disabled:opacity-(--opacity-disabled) data-[size=default]:h-6 data-[size=default]:w-11 data-[size=sm]:h-5 data-[size=sm]:w-9 data-[state=checked]:bg-background-brand-default data-[state=unchecked]:bg-border-default-default",
7371
7395
  className
7372
7396
  )
7373
7397
  }, props), {
@@ -7603,7 +7627,7 @@ import { cva as cva15 } from "class-variance-authority";
7603
7627
  import { Toggle as TogglePrimitive } from "radix-ui";
7604
7628
  import { jsx as jsx58 } from "react/jsx-runtime";
7605
7629
  var toggleVariants = cva15(
7606
- "type-toggle inline-flex items-center justify-center gap-2 rounded-md border border-border-default-default bg-background-primary-surface text-text-prominent-default whitespace-nowrap transition-[color,background-color,border-color,box-shadow] outline-none hover:bg-background-secondary-surface active:bg-background-secondary-wash focus-visible:border-ring-focus-default focus-visible:ring-[3px] focus-visible:ring-ring-focus-strong disabled:pointer-events-none disabled:border-border-default-default disabled:text-text-disabled-default aria-invalid:border-border-error-default aria-invalid:ring-ring-error-soft data-[state=on]:border-transparent data-[state=on]:bg-background-brand-default data-[state=on]:text-text-on-brand-static [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
7630
+ "type-toggle inline-flex items-center justify-center gap-2 rounded-md border border-border-default-default bg-background-primary-surface text-text-prominent-default whitespace-nowrap transition-[color,background-color,border-color,box-shadow] outline-none hover:bg-background-secondary-surface active:bg-background-secondary-wash focus-visible:border-ring-focus-default focus-visible:ring-[3px] focus-visible:ring-ring-focus-strong disabled:pointer-events-none disabled:opacity-(--opacity-disabled) aria-invalid:border-border-error-default aria-invalid:ring-ring-error-soft data-[state=on]:border-transparent data-[state=on]:bg-background-brand-default data-[state=on]:text-text-on-brand-static [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
7607
7631
  {
7608
7632
  variants: {
7609
7633
  size: {
@@ -8300,7 +8324,6 @@ function useSmoothProgress({
8300
8324
  const label = done && progress >= 99.5 ? readyLabel : (_b = (_a = checkpoints[idx]) == null ? void 0 : _a.label) != null ? _b : readyLabel;
8301
8325
  return { progress, label, delayed, complete: done && progress >= 100 };
8302
8326
  }
8303
- var MONOGRAM_D = "M513.51,265.27l12.26-58.98H183.8l-12.26,58.98h105.29l-46.92,225.76,29.68-.85c1.65-.05,40.84-1.34,87-18.36,64.47-23.76,111.8-66.23,136.88-122.83l15.77-35.6h-139.02l-12.26,58.98h58.44l-6.31,6.26c-3.16,3.14-6.56,6.2-10.11,9.12-14.15,11.63-31.27,21.29-50.86,28.7-10.01,3.79-20.64,6.97-31.57,9.45l-5.55,1.26,33.65-161.89h177.86Z";
8304
8327
  function GameLoadingBlock({
8305
8328
  progress = 0,
8306
8329
  label = "",
@@ -8308,6 +8331,7 @@ function GameLoadingBlock({
8308
8331
  exiting = false,
8309
8332
  onExitEnd,
8310
8333
  contained = false,
8334
+ logoSrc,
8311
8335
  backgroundImageUrl,
8312
8336
  className
8313
8337
  }) {
@@ -8321,13 +8345,15 @@ function GameLoadingBlock({
8321
8345
  React23.useEffect(() => {
8322
8346
  if (!exiting) return;
8323
8347
  const raf = requestAnimationFrame(() => setGo(true));
8324
- const timer = setTimeout(() => onExitEnd == null ? void 0 : onExitEnd(), reduced ? 240 : 520);
8348
+ const timer = setTimeout(() => onExitEnd == null ? void 0 : onExitEnd(), reduced ? 240 : 700);
8325
8349
  return () => {
8326
8350
  cancelAnimationFrame(raf);
8327
8351
  clearTimeout(timer);
8328
8352
  };
8329
8353
  }, [exiting, reduced, onExitEnd]);
8330
8354
  const isAbsolute = exiting || contained;
8355
+ const punched = Boolean(logoSrc);
8356
+ const animate = exiting && go && !reduced;
8331
8357
  return /* @__PURE__ */ jsxs40(
8332
8358
  "div",
8333
8359
  {
@@ -8336,39 +8362,51 @@ function GameLoadingBlock({
8336
8362
  "aria-label": "Loading game",
8337
8363
  "data-slot": "game-loading-block",
8338
8364
  className: cn(
8339
- "z-50 inset-0 flex flex-col items-center justify-center gap-8 overflow-hidden",
8365
+ "z-50 inset-0 overflow-hidden",
8340
8366
  isAbsolute ? "absolute" : "fixed",
8341
- // Token-derived dotted brand backdrop; skipped when a real image is passed.
8342
- !backgroundImageUrl && "game-loader-backdrop",
8343
- backgroundImageUrl && "bg-primary bg-cover bg-center bg-no-repeat",
8344
- exiting && (reduced ? "transition-opacity duration-200" : "transition-opacity duration-[180ms] delay-[260ms]"),
8345
- exiting && go ? "opacity-0" : "opacity-100",
8367
+ // Reduced motion, and the no-mark fallback, fade the whole layer.
8368
+ exiting && (reduced || !punched) && "transition-opacity duration-200",
8369
+ exiting && go && (reduced || !punched) ? "opacity-0" : "opacity-100",
8346
8370
  className
8347
8371
  ),
8348
- style: backgroundImageUrl ? { backgroundImage: `url(${backgroundImageUrl})` } : void 0,
8349
8372
  children: [
8350
8373
  /* @__PURE__ */ jsx67(
8351
- "svg",
8374
+ "div",
8375
+ {
8376
+ "aria-hidden": "true",
8377
+ "data-slot": "game-loading-backdrop",
8378
+ className: cn(
8379
+ "game-loader-field",
8380
+ punched && "game-loader-punch",
8381
+ animate && punched && "game-loader-field-exit"
8382
+ ),
8383
+ style: __spreadValues(__spreadValues({}, logoSrc ? { "--game-loader-mark": `url(${logoSrc})` } : null), backgroundImageUrl ? {
8384
+ backgroundImage: `url(${backgroundImageUrl})`,
8385
+ backgroundSize: "cover",
8386
+ backgroundPosition: "center",
8387
+ backgroundRepeat: "no-repeat"
8388
+ } : null)
8389
+ }
8390
+ ),
8391
+ logoSrc && /* @__PURE__ */ jsx67(
8392
+ "img",
8352
8393
  {
8353
- width: "120",
8354
- height: "120",
8355
- viewBox: "0 0 697.31 697.31",
8356
- xmlns: "http://www.w3.org/2000/svg",
8394
+ src: logoSrc,
8395
+ alt: "",
8357
8396
  "aria-hidden": "true",
8358
- className: cn("game-loader-mark fill-on-primary", exiting && go && !reduced && "game-loader-mark-exit"),
8359
- children: /* @__PURE__ */ jsx67("path", { d: MONOGRAM_D })
8397
+ className: cn("game-loader-mark", animate && "game-loader-mark-exit")
8360
8398
  }
8361
8399
  ),
8362
- !exiting && /* @__PURE__ */ jsxs40("div", { className: "flex w-[200px] flex-col items-start gap-3.5", children: [
8363
- /* @__PURE__ */ jsx67("div", { className: "relative h-2 w-full overflow-hidden rounded-xs bg-on-primary/25", children: /* @__PURE__ */ jsx67(
8400
+ !exiting && /* @__PURE__ */ jsxs40("div", { className: "absolute bottom-10 left-1/2 flex w-[200px] -translate-x-1/2 flex-col items-start gap-3.5", children: [
8401
+ /* @__PURE__ */ jsx67("div", { className: "relative h-2 w-full overflow-hidden rounded-xs bg-background-secondary-surface", children: /* @__PURE__ */ jsx67(
8364
8402
  "div",
8365
8403
  {
8366
- className: "absolute inset-y-0 left-0 overflow-hidden rounded-xs bg-on-primary",
8404
+ className: "absolute inset-y-0 left-0 overflow-hidden rounded-xs bg-background-brand-default",
8367
8405
  style: { width: `${progress}%` },
8368
8406
  children: /* @__PURE__ */ jsx67("span", { "aria-hidden": "true", className: "game-loader-shimmer absolute inset-y-0 left-[-60%] w-[60%]" })
8369
8407
  }
8370
8408
  ) }),
8371
- /* @__PURE__ */ jsx67("span", { className: "caption text-on-primary/90", children: delayed ? "Taking longer than usual\u2026" : label })
8409
+ /* @__PURE__ */ jsx67("span", { className: "caption text-text-subtle-default", children: delayed ? "Taking longer than usual\u2026" : label })
8372
8410
  ] })
8373
8411
  ]
8374
8412
  }