@stasho/ds 0.1.1 → 0.2.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.
@@ -8,12 +8,17 @@ import { cn } from "@ac/lib/cn";
8
8
  const triggerVariants = cva(
9
9
  [
10
10
  "inline-flex items-center justify-between",
11
- "w-full font-sans text-foreground bg-primary-100 dark:bg-base-700",
12
- "border-0 rounded-full",
13
- "focus-visible:outline-none focus-visible:ring-3",
14
- "focus-visible:ring-primary-500",
15
- "disabled:opacity-50 disabled:pointer-events-none",
16
- "ring-0 transition-colors",
11
+ "w-full font-sans text-foreground",
12
+ "bg-background dark:bg-surface",
13
+ "border border-edge rounded-none",
14
+ "hover:border-edge-hover",
15
+ "focus-visible:outline-none",
16
+ "focus-visible:border-accent-700 dark:focus-visible:border-accent",
17
+ "disabled:bg-muted dark:disabled:bg-background",
18
+ "disabled:border-edge/50",
19
+ "disabled:text-foreground/30",
20
+ "disabled:cursor-not-allowed",
21
+ "transition-colors",
17
22
  ].join(" "),
18
23
  {
19
24
  variants: {
@@ -82,8 +87,10 @@ const Combobox = forwardRef<HTMLButtonElement, ComboboxProps>(
82
87
  aria-invalid={error || undefined}
83
88
  className={cn(
84
89
  triggerVariants({ size }),
85
- error && "border-3 border-error-400 hover:border-error-500",
86
- !selectedLabel && "text-muted-foreground",
90
+ error &&
91
+ "border-error hover:border-error focus-visible:border-error dark:focus-visible:border-error",
92
+ !selectedLabel &&
93
+ (disabled ? "text-muted-foreground/50" : "text-muted-foreground"),
87
94
  className,
88
95
  )}
89
96
  {...rest}
@@ -105,8 +112,8 @@ const Combobox = forwardRef<HTMLButtonElement, ComboboxProps>(
105
112
  <Popover.Content
106
113
  className={cn(
107
114
  "z-50 w-[var(--radix-popover-trigger-width)]",
108
- "overflow-hidden rounded-2xl",
109
- "bg-surface border border-edge shadow-brand",
115
+ "overflow-hidden rounded-none",
116
+ "bg-popover-bg border border-popover-border shadow",
110
117
  )}
111
118
  sideOffset={4}
112
119
  align="start"
@@ -134,12 +141,12 @@ const Combobox = forwardRef<HTMLButtonElement, ComboboxProps>(
134
141
  setOpen(false);
135
142
  }}
136
143
  className={cn(
137
- "relative flex items-center rounded-xl px-4 py-2",
144
+ "relative flex items-center rounded-none px-4 py-2",
138
145
  "text-sm text-foreground cursor-pointer select-none",
139
146
  "outline-none",
140
147
  "data-[selected=true]:bg-muted",
141
- "data-[disabled=true]:opacity-50",
142
- "data-[disabled=true]:pointer-events-none",
148
+ "data-[disabled=true]:text-foreground/30",
149
+ "data-[disabled=true]:cursor-not-allowed",
143
150
  )}
144
151
  >
145
152
  <span className="flex-1">{option.label}</span>
@@ -98,7 +98,7 @@ const CopyableText = forwardRef<HTMLSpanElement, CopyableTextProps>(
98
98
  ref={ref}
99
99
  className={cn(
100
100
  copyableTextVariants({ size }),
101
- href && "text-primary-500 dark:text-primary-300",
101
+ href && "text-accent-500 dark:text-accent",
102
102
  className,
103
103
  )}
104
104
  {...rest}
@@ -125,7 +125,7 @@ const CopyableText = forwardRef<HTMLSpanElement, CopyableTextProps>(
125
125
  onClick={handleCopy}
126
126
  className={cn(
127
127
  "relative inline-flex items-center justify-center",
128
- "rounded-md cursor-pointer",
128
+ "rounded-none cursor-pointer",
129
129
  "hover:bg-foreground/10 transition-colors",
130
130
  btnCn,
131
131
  )}
@@ -170,7 +170,7 @@ const CopyableText = forwardRef<HTMLSpanElement, CopyableTextProps>(
170
170
  rel="noopener noreferrer"
171
171
  onClick={(e) => e.stopPropagation()}
172
172
  className={cn(
173
- "inline-flex items-center justify-center rounded-md",
173
+ "inline-flex items-center justify-center rounded-none",
174
174
  "text-muted-foreground hover:text-foreground",
175
175
  "hover:bg-foreground/10 transition-colors",
176
176
  btnCn,
@@ -38,7 +38,7 @@ const DialogContent = forwardRef<HTMLDivElement, DialogContentProps>(
38
38
  <DialogPrimitive.Content
39
39
  ref={ref}
40
40
  className={cn(
41
- "relative w-full max-w-md rounded-md bg-surface p-6 shadow-brand-lg",
41
+ "relative w-full max-w-md rounded-xl bg-surface p-6",
42
42
  "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
43
43
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
44
44
  "motion-reduce:animate-none",
@@ -56,10 +56,9 @@ const DialogContent = forwardRef<HTMLDivElement, DialogContentProps>(
56
56
  {locked ? null : (
57
57
  <DialogPrimitive.Close
58
58
  className={cn(
59
- "absolute top-4 right-4 rounded-sm",
59
+ "absolute top-4 right-4 rounded-none",
60
60
  "text-muted-foreground transition-colors hover:text-foreground",
61
- "focus-visible:outline-none focus-visible:ring-2",
62
- "focus-visible:ring-primary-400 focus-visible:ring-offset-2",
61
+ "focus-visible:outline-2 focus-visible:outline-accent focus-visible:outline-offset-2",
63
62
  )}
64
63
  aria-label="Close"
65
64
  >
@@ -47,14 +47,14 @@ function FormField({
47
47
  >
48
48
  {label}
49
49
  {required && (
50
- <span className="text-error-600 ml-0.5" aria-hidden="true">
50
+ <span className="text-error ml-0.5" aria-hidden="true">
51
51
  *
52
52
  </span>
53
53
  )}
54
54
  </label>
55
55
  {child}
56
56
  {error ? (
57
- <p id={messageId} role="alert" className="text-xs text-error-600">
57
+ <p id={messageId} role="alert" className="text-xs text-error">
58
58
  {error}
59
59
  </p>
60
60
  ) : helperText ? (
@@ -4,13 +4,18 @@ import { cn } from "@ac/lib/cn";
4
4
 
5
5
  const inputVariants = cva(
6
6
  [
7
- "w-full font-sans text-foreground bg-primary-100 dark:bg-base-700",
8
- "border-0 rounded-full",
7
+ "w-full font-sans text-foreground",
8
+ "bg-background dark:bg-surface",
9
+ "border border-edge rounded-none",
9
10
  "placeholder:text-muted-foreground",
10
- "focus-visible:outline-none focus-visible:ring-3",
11
- "focus-visible:ring-primary-500",
12
- "disabled:opacity-50 disabled:pointer-events-none",
13
- "ring-0 transition-colors",
11
+ "focus-visible:outline-none",
12
+ "focus-visible:border-accent-700 dark:focus-visible:border-accent",
13
+ "disabled:bg-muted dark:disabled:bg-background",
14
+ "disabled:border-edge/50",
15
+ "disabled:text-foreground/30",
16
+ "disabled:placeholder:text-muted-foreground/50",
17
+ "disabled:cursor-not-allowed",
18
+ "transition-colors",
14
19
  ].join(" "),
15
20
  {
16
21
  variants: {
@@ -37,7 +42,8 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
37
42
  ref={ref}
38
43
  className={cn(
39
44
  inputVariants({ size }),
40
- error && "border-3 border-error-400 hover:border-error-500",
45
+ error &&
46
+ "border-error hover:border-error focus-visible:border-error dark:focus-visible:border-error",
41
47
  className,
42
48
  )}
43
49
  aria-invalid={error || undefined}
@@ -8,12 +8,17 @@ import { cn } from "@ac/lib/cn";
8
8
  const triggerVariants = cva(
9
9
  [
10
10
  "inline-flex items-center gap-1.5",
11
- "w-full font-sans text-foreground bg-primary-100 dark:bg-base-700",
12
- "border-0 rounded-2xl",
13
- "focus-visible:outline-none focus-visible:ring-3",
14
- "focus-visible:ring-primary-500",
15
- "aria-disabled:opacity-50 aria-disabled:pointer-events-none",
16
- "ring-0 transition-colors",
11
+ "w-full font-sans text-foreground",
12
+ "bg-background dark:bg-surface",
13
+ "border border-edge rounded-none",
14
+ "hover:border-edge-hover",
15
+ "focus-visible:outline-none",
16
+ "focus-visible:border-accent-700 dark:focus-visible:border-accent",
17
+ "aria-disabled:bg-muted dark:aria-disabled:bg-background",
18
+ "aria-disabled:border-edge/50",
19
+ "aria-disabled:text-foreground/30",
20
+ "aria-disabled:cursor-not-allowed",
21
+ "transition-colors",
17
22
  ].join(" "),
18
23
  {
19
24
  variants: {
@@ -30,7 +35,7 @@ const triggerVariants = cva(
30
35
 
31
36
  const tagVariants = cva(
32
37
  [
33
- "inline-flex items-center gap-1 rounded-full bg-muted",
38
+ "inline-flex items-center gap-1 rounded-[2px] bg-muted",
34
39
  "text-foreground max-w-32 select-none",
35
40
  ].join(" "),
36
41
  {
@@ -137,8 +142,11 @@ const MultiSelect = forwardRef<HTMLDivElement, MultiSelectProps>(
137
142
  triggerVariants({ size }),
138
143
  "cursor-pointer",
139
144
  error &&
140
- "border-3 border-error-400 hover:border-error-500",
141
- !hasSelection && "text-muted-foreground",
145
+ "border-error hover:border-error focus-visible:border-error dark:focus-visible:border-error",
146
+ !hasSelection &&
147
+ (disabled
148
+ ? "text-muted-foreground/50"
149
+ : "text-muted-foreground"),
142
150
  className,
143
151
  )}
144
152
  {...rest}
@@ -157,7 +165,7 @@ const MultiSelect = forwardRef<HTMLDivElement, MultiSelectProps>(
157
165
  aria-label={`Remove ${opt.label}`}
158
166
  onClick={(e) => removeTag(e, opt.value)}
159
167
  className={cn(
160
- "shrink-0 rounded-full",
168
+ "shrink-0 rounded-[2px]",
161
169
  "hover:bg-foreground/10 transition-colors",
162
170
  size === "sm" ? "size-3.5" : "size-4",
163
171
  )}
@@ -187,7 +195,7 @@ const MultiSelect = forwardRef<HTMLDivElement, MultiSelectProps>(
187
195
  aria-label="Clear all"
188
196
  onClick={clearAll}
189
197
  className={cn(
190
- "shrink-0 rounded-full",
198
+ "shrink-0 rounded-[2px]",
191
199
  "text-muted-foreground",
192
200
  "hover:text-foreground transition-colors",
193
201
  size === "sm" ? "size-4" : "size-5",
@@ -224,8 +232,8 @@ const MultiSelect = forwardRef<HTMLDivElement, MultiSelectProps>(
224
232
  <Popover.Content
225
233
  className={cn(
226
234
  "z-50 w-[var(--radix-popover-trigger-width)]",
227
- "overflow-hidden rounded-2xl",
228
- "bg-surface border border-edge shadow-brand",
235
+ "overflow-hidden rounded-none",
236
+ "bg-popover-bg border border-popover-border shadow",
229
237
  )}
230
238
  sideOffset={4}
231
239
  align="start"
@@ -260,22 +268,22 @@ const MultiSelect = forwardRef<HTMLDivElement, MultiSelectProps>(
260
268
  onSelect={() => toggle(option.value)}
261
269
  className={cn(
262
270
  "relative flex items-center gap-2",
263
- "rounded-xl px-3 py-2",
271
+ "rounded-none px-3 py-2",
264
272
  "text-sm text-foreground",
265
273
  "cursor-pointer select-none",
266
274
  "outline-none",
267
275
  "data-[selected=true]:bg-muted",
268
- "data-[disabled=true]:opacity-50",
269
- "data-[disabled=true]:pointer-events-none",
276
+ "data-[disabled=true]:text-foreground/30",
277
+ "data-[disabled=true]:cursor-not-allowed",
270
278
  )}
271
279
  >
272
280
  <span
273
281
  className={cn(
274
282
  "flex size-4 shrink-0 items-center",
275
283
  "justify-center",
276
- "rounded border-2 transition-colors",
284
+ "rounded-none border transition-colors",
277
285
  selected
278
- ? "border-primary bg-primary text-primary-foreground"
286
+ ? "border-accent bg-accent text-accent-foreground"
279
287
  : "border-edge bg-surface",
280
288
  )}
281
289
  aria-hidden="true"
@@ -80,28 +80,26 @@ type PaginationProps = Omit<HTMLAttributes<HTMLElement>, "onChange"> & {
80
80
 
81
81
  const NAV_BUTTON = [
82
82
  "inline-flex items-center justify-center",
83
- "size-8 rounded-full",
84
- "text-primary-600 dark:text-primary-400",
85
- "hover:bg-primary-100 dark:hover:bg-primary-200/10",
83
+ "size-8 rounded-none",
84
+ "text-foreground/60 hover:text-accent-500 dark:hover:text-accent",
86
85
  "transition-colors cursor-pointer",
87
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500",
86
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
88
87
  ].join(" ");
89
88
 
90
- const NAV_DISABLED = "opacity-50 pointer-events-none";
89
+ const NAV_DISABLED = "text-foreground/30 cursor-not-allowed";
91
90
 
92
91
  const PAGE_BUTTON = [
93
92
  "inline-flex items-center justify-center",
94
- "size-8 rounded-full",
95
- "font-heading font-bold text-lg",
96
- "text-primary-600 dark:text-primary-400",
97
- "hover:bg-primary-100 dark:hover:bg-primary-200/10",
93
+ "size-[26px] rounded-none",
94
+ "font-mono text-sm",
95
+ "text-foreground/60 hover:text-accent-500 dark:hover:text-accent",
98
96
  "transition-colors cursor-pointer",
99
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500",
97
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
100
98
  ].join(" ");
101
99
 
102
100
  const PAGE_ACTIVE = [
103
- "bg-primary-400 text-white dark:bg-primary-600 dark:text-white",
104
- "hover:bg-primary-400 dark:hover:bg-primary-600",
101
+ "bg-accent/15 text-accent-500 dark:text-accent",
102
+ "hover:text-accent-500 dark:hover:text-accent",
105
103
  ].join(" ");
106
104
 
107
105
  const Pagination = forwardRef<HTMLElement, PaginationProps>(
@@ -164,7 +162,7 @@ const Pagination = forwardRef<HTMLElement, PaginationProps>(
164
162
  item === "ellipsis" ? (
165
163
  <span
166
164
  key={i}
167
- className="inline-flex items-center justify-center size-8 font-heading font-bold text-lg text-primary-600 dark:text-primary-400 select-none"
165
+ className="inline-flex items-center justify-center size-[26px] font-mono text-sm text-foreground/40 select-none"
168
166
  aria-hidden="true"
169
167
  >
170
168
  {"\u2026"}
@@ -13,7 +13,11 @@ import { cn } from "@ac/lib/cn";
13
13
  /* ── Variants ──────────────────────────────────── */
14
14
 
15
15
  const progressBarVariants = cva(
16
- "relative rounded-full bg-surface overflow-hidden",
16
+ [
17
+ "relative rounded-full overflow-hidden",
18
+ "bg-muted dark:bg-neutral-900",
19
+ "shadow-[inset_0_1px_0_rgba(255,255,255,0.06),inset_0_-1px_0_rgba(0,0,0,0.4)]",
20
+ ].join(" "),
17
21
  {
18
22
  variants: {
19
23
  size: {
@@ -89,7 +93,7 @@ const ProgressBar = forwardRef<HTMLDivElement, ProgressBarProps>(
89
93
  data-fill=""
90
94
  data-indeterminate={indeterminate ? "" : undefined}
91
95
  className={cn(
92
- "h-full rounded-full bg-primary",
96
+ "h-full rounded-full bg-accent",
93
97
  indeterminate
94
98
  ? "animate-progress-indeterminate"
95
99
  : "transition-all",
@@ -5,21 +5,26 @@ import { cn } from "@ac/lib/cn";
5
5
 
6
6
  const radioItemVariants = cva(
7
7
  [
8
- "peer shrink-0 rounded-full bg-surface",
9
- "border-3 border-edge",
8
+ "peer shrink-0 rounded-full",
9
+ "bg-background dark:bg-surface",
10
+ "border border-edge",
10
11
  "hover:border-edge-hover",
11
- "focus-visible:outline-none focus-visible:ring-3",
12
- "focus-visible:ring-primary-500",
13
- "disabled:opacity-50 disabled:pointer-events-none",
14
- "data-[state=checked]:border-primary",
12
+ "focus-visible:outline-none",
13
+ "focus-visible:border-accent-700 dark:focus-visible:border-accent",
14
+ "disabled:bg-muted dark:disabled:bg-background",
15
+ "disabled:border-edge/50",
16
+ "disabled:cursor-not-allowed",
17
+ "disabled:[&_span]:bg-foreground/30",
18
+ "disabled:data-[state=checked]:border-edge/50",
19
+ "data-[state=checked]:border-accent",
15
20
  "transition-colors",
16
21
  ].join(" "),
17
22
  {
18
23
  variants: {
19
24
  size: {
20
- xs: "size-4",
21
- sm: "size-5",
22
- md: "size-6",
25
+ xs: "size-3.5",
26
+ sm: "size-4",
27
+ md: "size-5",
23
28
  },
24
29
  },
25
30
  defaultVariants: {
@@ -70,7 +75,7 @@ const RadioGroupItem = forwardRef<HTMLButtonElement, RadioGroupItemProps>(
70
75
  "transition-[clip-path] duration-200 ease-in-out motion-reduce:transition-none",
71
76
  )}
72
77
  >
73
- <span className="block size-[80%] rounded-full bg-primary" />
78
+ <span className="block size-[80%] rounded-full bg-accent" />
74
79
  </RadioGroupPrimitive.Indicator>
75
80
  </RadioGroupPrimitive.Item>
76
81
  );
@@ -7,13 +7,19 @@ import { cn } from "@ac/lib/cn";
7
7
  const triggerVariants = cva(
8
8
  [
9
9
  "inline-flex items-center justify-between",
10
- "w-full font-sans text-foreground bg-primary-100 dark:bg-base-700",
11
- "border-0 rounded-full",
12
- "focus-visible:outline-none focus-visible:ring-3",
13
- "focus-visible:ring-primary-500",
14
- "disabled:opacity-50 disabled:pointer-events-none",
15
- "ring-0 transition-colors",
10
+ "w-full font-sans text-foreground",
11
+ "bg-background dark:bg-surface",
12
+ "border border-edge rounded-none",
13
+ "hover:border-edge-hover",
14
+ "focus-visible:outline-none",
15
+ "focus-visible:border-accent-700 dark:focus-visible:border-accent",
16
+ "disabled:bg-muted dark:disabled:bg-background",
17
+ "disabled:border-edge/50",
18
+ "disabled:text-foreground/30",
19
+ "disabled:cursor-not-allowed",
20
+ "transition-colors",
16
21
  "data-[placeholder]:text-muted-foreground",
22
+ "disabled:data-[placeholder]:text-muted-foreground/50",
17
23
  ].join(" "),
18
24
  {
19
25
  variants: {
@@ -70,7 +76,8 @@ const Select = forwardRef<HTMLButtonElement, SelectProps>(
70
76
  aria-invalid={error || undefined}
71
77
  className={cn(
72
78
  triggerVariants({ size }),
73
- error && "border-3 border-error-400 hover:border-error-500",
79
+ error &&
80
+ "border-error hover:border-error focus-visible:border-error dark:focus-visible:border-error",
74
81
  className,
75
82
  )}
76
83
  >
@@ -82,8 +89,8 @@ const Select = forwardRef<HTMLButtonElement, SelectProps>(
82
89
  <SelectPrimitive.Portal>
83
90
  <SelectPrimitive.Content
84
91
  className={cn(
85
- "z-50 overflow-hidden rounded-2xl",
86
- "bg-surface border border-edge shadow-brand",
92
+ "z-50 overflow-hidden rounded-none",
93
+ "bg-popover-bg border border-popover-border shadow",
87
94
  )}
88
95
  position="popper"
89
96
  sideOffset={4}
@@ -95,12 +102,12 @@ const Select = forwardRef<HTMLButtonElement, SelectProps>(
95
102
  value={option.value}
96
103
  disabled={option.disabled ?? false}
97
104
  className={cn(
98
- "relative flex items-center rounded-xl px-4 py-2",
105
+ "relative flex items-center rounded-none px-4 py-2",
99
106
  "text-sm text-foreground cursor-pointer select-none",
100
107
  "outline-none",
101
108
  "data-[highlighted]:bg-muted",
102
- "data-[disabled]:opacity-50",
103
- "data-[disabled]:pointer-events-none",
109
+ "data-[disabled]:text-foreground/30",
110
+ "data-[disabled]:cursor-not-allowed",
104
111
  )}
105
112
  >
106
113
  <SelectPrimitive.ItemText>
@@ -6,7 +6,8 @@ import { cn } from "@ac/lib/cn";
6
6
  const trackVariants = cva(
7
7
  [
8
8
  "relative w-full grow overflow-hidden rounded-full",
9
- "bg-neutral-200 dark:bg-base-700",
9
+ "bg-muted dark:bg-neutral-900",
10
+ "shadow-[inset_0_1px_0_rgba(255,255,255,0.06),inset_0_-1px_0_rgba(0,0,0,0.4)]",
10
11
  ].join(" "),
11
12
  {
12
13
  variants: {
@@ -23,17 +24,22 @@ const trackVariants = cva(
23
24
 
24
25
  const thumbVariants = cva(
25
26
  [
26
- "block rounded-full bg-white",
27
- "border-2 border-primary-500",
28
- "focus-visible:outline-none focus-visible:ring-3",
29
- "focus-visible:ring-primary-500",
30
- "disabled:pointer-events-none",
27
+ "block rounded-full bg-background",
28
+ "border-[1.5px] border-accent",
29
+ "transition-[background-color,box-shadow] motion-reduce:transition-none",
30
+ "hover:bg-accent",
31
+ "hover:shadow-[0_0_6px_var(--accent),0_0_12px_rgba(0,225,250,0.5)]",
32
+ "focus-visible:outline-2 focus-visible:outline-accent focus-visible:outline-offset-2",
33
+ "focus-visible:shadow-[0_0_6px_var(--accent),0_0_12px_rgba(0,225,250,0.5)]",
34
+ "data-[disabled]:bg-background data-[disabled]:border-foreground/30",
35
+ "data-[disabled]:hover:bg-background",
36
+ "data-[disabled]:shadow-none data-[disabled]:cursor-not-allowed",
31
37
  ].join(" "),
32
38
  {
33
39
  variants: {
34
40
  size: {
35
- sm: "size-4",
36
- md: "size-5",
41
+ sm: "size-3",
42
+ md: "size-3.5",
37
43
  },
38
44
  },
39
45
  defaultVariants: {
@@ -80,7 +86,7 @@ const Slider = forwardRef<
80
86
  {...(disabled ? { disabled: true } : {})}
81
87
  className={cn(
82
88
  "relative flex w-full touch-none select-none items-center",
83
- disabled && "opacity-50 pointer-events-none",
89
+ disabled && "cursor-not-allowed",
84
90
  className,
85
91
  )}
86
92
  onValueChange={(val) => {
@@ -91,25 +97,25 @@ const Slider = forwardRef<
91
97
  onPointerLeave={() => setHovering(false)}
92
98
  {...rootProps}
93
99
  >
94
- <SliderPrimitive.Track
95
- className={cn(
96
- trackVariants({ size }),
97
- error && "ring-2 ring-error-400",
98
- )}
99
- >
100
- <SliderPrimitive.Range className="absolute h-full bg-primary-500 rounded-full" />
100
+ <SliderPrimitive.Track className={cn(trackVariants({ size }))}>
101
+ <SliderPrimitive.Range className="absolute h-full bg-accent data-[disabled]:bg-foreground/30 rounded-full" />
101
102
  </SliderPrimitive.Track>
102
103
  {displayValue.map((val, i) => (
103
104
  <SliderPrimitive.Thumb
104
105
  key={i}
105
- className={cn(thumbVariants({ size }), "relative")}
106
+ className={cn(
107
+ thumbVariants({ size }),
108
+ "relative",
109
+ error &&
110
+ "border-error hover:bg-error hover:shadow-[0_0_6px_var(--error),0_0_12px_rgba(255,61,0,0.5)] focus-visible:shadow-[0_0_6px_var(--error),0_0_12px_rgba(255,61,0,0.5)] focus-visible:outline-error",
111
+ )}
106
112
  >
107
113
  {showTooltip && hovering && (
108
114
  <span
109
115
  className={cn(
110
116
  "absolute bottom-full left-1/2 -translate-x-1/2 mb-2",
111
- "rounded-md bg-neutral-900 dark:bg-base-700 px-2 py-1",
112
- "text-xs text-white whitespace-nowrap pointer-events-none",
117
+ "rounded-none bg-popover-bg border border-popover-border px-2 py-1",
118
+ "text-xs text-foreground whitespace-nowrap pointer-events-none",
113
119
  )}
114
120
  >
115
121
  {val}
@@ -6,6 +6,7 @@ import {
6
6
  useContext,
7
7
  type HTMLAttributes,
8
8
  } from "react";
9
+ import { Check } from "@phosphor-icons/react";
9
10
  import { cn } from "@ac/lib/cn";
10
11
 
11
12
  /* ── Stepper context (orientation) ─────────────── */
@@ -114,23 +115,22 @@ const StepperIndicator = forwardRef<HTMLDivElement, StepperIndicatorProps>(
114
115
  ref={ref}
115
116
  data-state={state}
116
117
  className={cn(
117
- "relative flex size-8 items-center justify-center rounded-full",
118
- "font-heading text-sm font-bold",
119
- "border-2 border-edge text-muted-foreground",
120
- "data-[state=active]:border-primary-500 data-[state=active]:bg-primary-500 data-[state=active]:text-white",
121
- "data-[state=completed]:border-primary-500 data-[state=completed]:bg-primary-500 data-[state=completed]:text-white",
122
- "transition-all duration-300 motion-reduce:transition-colors",
118
+ "relative flex size-8 items-center justify-center rounded-[2px]",
119
+ "font-sans text-sm font-semibold",
120
+ "border border-edge text-foreground/45 bg-transparent",
121
+ "data-[state=active]:border-accent data-[state=active]:text-accent-500 dark:data-[state=active]:text-accent",
122
+ "data-[state=active]:shadow-[0_0_6px_rgba(0,225,250,0.5),0_0_14px_rgba(0,225,250,0.3)]",
123
+ "data-[state=completed]:border-accent data-[state=completed]:bg-accent data-[state=completed]:text-neutral-950",
124
+ "transition-all duration-200 motion-reduce:transition-colors",
123
125
  className,
124
126
  )}
125
127
  {...rest}
126
128
  >
127
- {state === "active" && (
128
- <>
129
- <span className="absolute -inset-1 rounded-full border-2 border-primary-400/35 animate-[ring-wave_2.4s_ease-in-out_infinite] motion-reduce:animate-none" />
130
- <span className="absolute -inset-1.5 rounded-full border border-primary-300/25 animate-[ring-wave_2.4s_ease-in-out_-1.2s_infinite] motion-reduce:animate-none" />
131
- </>
129
+ {state === "completed" ? (
130
+ <Check weight="bold" className="size-4" aria-hidden="true" />
131
+ ) : (
132
+ children
132
133
  )}
133
- {children}
134
134
  </div>
135
135
  );
136
136
  },
@@ -186,19 +186,23 @@ StepperDescription.displayName = "StepperDescription";
186
186
 
187
187
  /* ── StepperConnector (li, visual line) ────────── */
188
188
 
189
- type StepperConnectorProps = HTMLAttributes<HTMLLIElement>;
189
+ type StepperConnectorProps = HTMLAttributes<HTMLLIElement> & {
190
+ /** Mark the connector as filled (cyan) — used between two consecutive completed steps. */
191
+ completed?: boolean;
192
+ };
190
193
 
191
194
  const StepperConnector = forwardRef<HTMLLIElement, StepperConnectorProps>(
192
- ({ className, ...rest }, ref) => {
195
+ ({ className, completed, ...rest }, ref) => {
193
196
  const { orientation } = useStepperContext();
194
197
  return (
195
198
  <li
196
199
  ref={ref}
197
200
  aria-hidden="true"
198
201
  data-orientation={orientation}
202
+ data-completed={completed ? "" : undefined}
199
203
  className={cn(
200
- "relative overflow-hidden rounded-full bg-edge/50 flex-1",
201
- orientation === "horizontal" ? "h-1" : "w-1",
204
+ "relative overflow-hidden flex-1 bg-edge data-[completed]:bg-accent transition-colors",
205
+ orientation === "horizontal" ? "h-px" : "w-px",
202
206
  className,
203
207
  )}
204
208
  {...rest}