@stacksjs/components 0.2.176 → 0.2.178

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.
Files changed (109) hide show
  1. package/dist/{Accordion-pt8j917s.stx → Accordion-8tv78bh9.stx} +4 -4
  2. package/dist/{AccordionItem-hbhzx63p.stx → AccordionItem-7bd3ga36.stx} +3 -3
  3. package/dist/{Audio-hjywk3qc.stx → Audio-y0sgq50z.stx} +3 -3
  4. package/dist/{Avatar-h3jmwcq0.stx → Avatar-rjvwnskf.stx} +2 -2
  5. package/dist/{Badge-k8dy3d53.stx → Badge-k52qmxcm.stx} +1 -1
  6. package/dist/{Breadcrumb-7f7s4d02.stx → Breadcrumb-sy5taqsn.stx} +7 -7
  7. package/dist/{Button-1vknasy3.stx → Button-wrwmnfpf.stx} +2 -2
  8. package/dist/{Calendar-reny0et7.stx → Calendar-gjjhhfnt.stx} +8 -8
  9. package/dist/{Card-c1g1fd1w.stx → Card-473a02fy.stx} +3 -3
  10. package/dist/{Checkbox-aqmq4cqv.stx → Checkbox-2s2a7n4h.stx} +4 -4
  11. package/dist/{Checkout-agt0ngpw.stx → Checkout-22wh3s22.stx} +1 -1
  12. package/dist/{ComboboxOption-hmxt3gte.stx → ComboboxOption-6yh7xk7q.stx} +2 -2
  13. package/dist/{CommandPaletteItem-mvk6q7a2.stx → CommandPaletteItem-chdw0070.stx} +1 -1
  14. package/dist/{DefaultPaymentMethod-shhf6aap.stx → DefaultPaymentMethod-6qrem3sg.stx} +8 -8
  15. package/dist/{DialogDescription-76prd1m2.stx → DialogDescription-gth4c2kx.stx} +1 -1
  16. package/dist/{Drawer-hrz7qcyp.stx → Drawer-jgepqr9j.stx} +1 -1
  17. package/dist/{DropdownItem-c7rz08e5.stx → DropdownItem-d8ht2bp5.stx} +1 -1
  18. package/dist/{Form-bpnpbymb.stx → Form-vbag14t1.stx} +1 -1
  19. package/dist/{ListboxOption-e0dtv1gc.stx → ListboxOption-4j070101.stx} +2 -2
  20. package/dist/{Login-gepemsth.stx → Login-2cp65d41.stx} +40 -22
  21. package/dist/{Navigator-rk2a5wvk.stx → Navigator-smpa7my4.stx} +12 -12
  22. package/dist/{NumberInput-g41gmd2c.stx → NumberInput-j9p5bm5y.stx} +7 -7
  23. package/dist/{Pagination-wtgxmzey.stx → Pagination-jbcjrfcs.stx} +3 -3
  24. package/dist/{PasswordInput-4rsq1gwb.stx → PasswordInput-4qykq1dz.stx} +8 -8
  25. package/dist/{PaymentMethods-x4vrx9yb.stx → PaymentMethods-2xy66bwk.stx} +11 -11
  26. package/dist/{Progress-9dhakbh4.stx → Progress-4h7dytq5.stx} +9 -9
  27. package/dist/{Radio-djtb5dpc.stx → Radio-ccm07b2m.stx} +4 -4
  28. package/dist/RadioGroup-eerw9gq7.stx +138 -0
  29. package/dist/{RadioGroupDescription-yej78fak.stx → RadioGroupDescription-z34r9avr.stx} +1 -1
  30. package/dist/{RadioGroupOption-s1d6r221.stx → RadioGroupOption-7pq7rw84.stx} +1 -1
  31. package/dist/{Select-1vnd0brz.stx → Select-zt72gg1e.stx} +4 -4
  32. package/dist/{SidebarItem-2a6n0be3.stx → SidebarItem-5v8atp7p.stx} +2 -2
  33. package/dist/{SidebarPinned-tvj28bm0.stx → SidebarPinned-rq05nrtd.stx} +3 -3
  34. package/dist/{Signup-hxm5hwkr.stx → Signup-cbncrtvd.stx} +29 -19
  35. package/dist/{Skeleton-v1pwa8nr.stx → Skeleton-wtwb97xd.stx} +1 -1
  36. package/dist/{Spinner-7dahavkd.stx → Spinner-ypya5tt2.stx} +8 -8
  37. package/dist/{StepperStep-wxgembat.stx → StepperStep-3ahq4d9m.stx} +3 -3
  38. package/dist/{SubscriptionCheckout-zy2ycrmw.stx → SubscriptionCheckout-7fdkwf04.stx} +40 -34
  39. package/dist/{Switch-p1bcr9ks.stx → Switch-hdta55a8.stx} +1 -1
  40. package/dist/{Table-6cx8az9h.stx → Table-0mc3fdek.stx} +1 -1
  41. package/dist/{TableBody-wf6t13j9.stx → TableBody-drxyz5jh.stx} +1 -1
  42. package/dist/{TableCell-ntx0edbn.stx → TableCell-8swtcq8s.stx} +1 -1
  43. package/dist/{TableHead-3k4hnm2k.stx → TableHead-e9xvjx2j.stx} +1 -1
  44. package/dist/{TableHeader-0eyzbqpz.stx → TableHeader-sxc77b4d.stx} +2 -2
  45. package/dist/{TableRow-z09p2ebf.stx → TableRow-xd542nvb.stx} +1 -1
  46. package/dist/{Tabs-79brys99.stx → Tabs-b4xsba1w.stx} +6 -6
  47. package/dist/{TextInput-g0vaz0pe.stx → TextInput-cefyyprt.stx} +9 -9
  48. package/dist/{Textarea-96kawv5c.stx → Textarea-xcdym703.stx} +6 -6
  49. package/dist/{TwoFactorChallenge-y5m3nk79.stx → TwoFactorChallenge-y7n4yrk9.stx} +8 -8
  50. package/dist/{Video-84j4pv6h.stx → Video-a0aeyexv.stx} +1 -1
  51. package/dist/{VirtualTable-f9crbfjr.stx → VirtualTable-jvm1784g.stx} +6 -6
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.js +89 -55
  54. package/dist/theme/index.d.ts +92 -0
  55. package/package.json +3 -3
  56. package/src/index.ts +2 -0
  57. package/src/theme/index.ts +130 -0
  58. package/src/ui/accordion/Accordion.stx +4 -4
  59. package/src/ui/accordion/AccordionItem.stx +3 -3
  60. package/src/ui/audio/Audio.stx +3 -3
  61. package/src/ui/auth/Login.stx +40 -22
  62. package/src/ui/auth/Signup.stx +29 -19
  63. package/src/ui/auth/TwoFactorChallenge.stx +8 -8
  64. package/src/ui/avatar/Avatar.stx +2 -2
  65. package/src/ui/badge/Badge.stx +1 -1
  66. package/src/ui/breadcrumb/Breadcrumb.stx +7 -7
  67. package/src/ui/button/Button.stx +2 -2
  68. package/src/ui/calendar/Calendar.stx +8 -8
  69. package/src/ui/card/Card.stx +3 -3
  70. package/src/ui/checkbox/Checkbox.stx +4 -4
  71. package/src/ui/combobox/ComboboxOption.stx +2 -2
  72. package/src/ui/command-palette/CommandPaletteItem.stx +1 -1
  73. package/src/ui/dialog/DialogDescription.stx +1 -1
  74. package/src/ui/drawer/Drawer.stx +1 -1
  75. package/src/ui/dropdown/DropdownItem.stx +1 -1
  76. package/src/ui/form/Form.stx +1 -1
  77. package/src/ui/input/NumberInput.stx +7 -7
  78. package/src/ui/input/PasswordInput.stx +8 -8
  79. package/src/ui/input/TextInput.stx +9 -9
  80. package/src/ui/listbox/ListboxOption.stx +2 -2
  81. package/src/ui/navigator/Navigator.stx +12 -12
  82. package/src/ui/pagination/Pagination.stx +3 -3
  83. package/src/ui/payment/Checkout.stx +1 -1
  84. package/src/ui/payment/DefaultPaymentMethod.stx +8 -8
  85. package/src/ui/payment/PaymentMethods.stx +11 -11
  86. package/src/ui/payment/SubscriptionCheckout.stx +40 -34
  87. package/src/ui/progress/Progress.stx +9 -9
  88. package/src/ui/radio/Radio.stx +4 -4
  89. package/src/ui/radio-group/RadioGroup.stx +79 -1
  90. package/src/ui/radio-group/RadioGroupDescription.stx +1 -1
  91. package/src/ui/radio-group/RadioGroupOption.stx +1 -1
  92. package/src/ui/select/Select.stx +4 -4
  93. package/src/ui/sidebar/SidebarItem.stx +2 -2
  94. package/src/ui/sidebar/SidebarPinned.stx +3 -3
  95. package/src/ui/skeleton/Skeleton.stx +1 -1
  96. package/src/ui/spinner/Spinner.stx +8 -8
  97. package/src/ui/stepper/StepperStep.stx +3 -3
  98. package/src/ui/switch/Switch.stx +1 -1
  99. package/src/ui/table/Table.stx +1 -1
  100. package/src/ui/table/TableBody.stx +1 -1
  101. package/src/ui/table/TableCell.stx +1 -1
  102. package/src/ui/table/TableHead.stx +1 -1
  103. package/src/ui/table/TableHeader.stx +2 -2
  104. package/src/ui/table/TableRow.stx +1 -1
  105. package/src/ui/tabs/Tabs.stx +6 -6
  106. package/src/ui/textarea/Textarea.stx +6 -6
  107. package/src/ui/video/Video.stx +1 -1
  108. package/src/ui/virtual-table/VirtualTable.stx +6 -6
  109. package/dist/RadioGroup-qxmnm3xm.stx +0 -60
@@ -18,16 +18,16 @@ const iconSizeClasses = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6' }
18
18
  const baseClasses = 'block w-full border-0 rounded-md shadow-sm ring-1 ring-inset transition-colors duration-200 focus:ring-2 focus:ring-inset dark:bg-blue-gray-700 dark:text-gray-100 pr-10'
19
19
  const stateClasses = error
20
20
  ? 'ring-red-300 dark:ring-red-600 text-red-900 dark:text-red-300 placeholder-red-300 dark:placeholder-red-500 focus:ring-red-500 dark:focus:ring-red-400'
21
- : 'ring-gray-300 dark:ring-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-indigo-600 dark:focus:ring-indigo-400'
21
+ : 'ring-line-strong text-fg placeholder-fg-subtle focus:ring-accent'
22
22
  const disabledClasses = disabled
23
- ? 'opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-800'
23
+ ? 'opacity-50 cursor-not-allowed bg-surface'
24
24
  : readonly
25
- ? 'bg-gray-50 dark:bg-gray-800 cursor-default'
25
+ ? 'bg-surface cursor-default'
26
26
  : 'bg-white dark:bg-blue-gray-700'
27
27
 
28
28
  export const inputClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses} ${inputClassName}`.trim()
29
- export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-900 dark:text-gray-100'}`.trim()
30
- export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
29
+ export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-danger' : 'text-fg'}`.trim()
30
+ export const helperClasses = `mt-2 text-sm ${error ? 'text-danger' : 'text-fg-soft'}`.trim()
31
31
  export const iconClasses = iconSizeClasses[size]
32
32
  </script>
33
33
 
@@ -105,7 +105,7 @@ defineExpose({ value: inputValue })
105
105
  <button
106
106
  type="button"
107
107
  @click="toggleVisibility()"
108
- class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 focus:outline-none"
108
+ class="text-fg-subtle hover:text-fg-muted focus:outline-none"
109
109
  :aria-label="toggleAriaLabel()"
110
110
  >
111
111
  <svg :show="showPassword()" class="{{ iconClasses }}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
@@ -122,10 +122,10 @@ defineExpose({ value: inputValue })
122
122
  @if(showStrength)
123
123
  <div :show="inputValue().length > 0" class="mt-2">
124
124
  <div class="flex items-center justify-between mb-1">
125
- <span class="text-xs text-gray-600 dark:text-gray-400">Password strength</span>
125
+ <span class="text-xs text-fg-muted">Password strength</span>
126
126
  <span class="text-xs font-medium" :class="strengthLabelColor()" x-text="strengthText()"></span>
127
127
  </div>
128
- <div class="w-full h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
128
+ <div class="w-full h-1.5 bg-surface-sunken rounded-full overflow-hidden">
129
129
  <div
130
130
  class="h-full transition-all duration-300 rounded-full"
131
131
  :class="strengthColor()"
@@ -22,17 +22,17 @@ const iconSizeClasses = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6' }
22
22
  const baseClasses = 'block w-full border-0 rounded-md shadow-sm ring-1 ring-inset transition-colors duration-200 focus:ring-2 focus:ring-inset dark:bg-blue-gray-700 dark:text-gray-100'
23
23
  const stateClasses = error
24
24
  ? 'ring-red-300 dark:ring-red-600 text-red-900 dark:text-red-300 placeholder-red-300 dark:placeholder-red-500 focus:ring-red-500 dark:focus:ring-red-400'
25
- : 'ring-gray-300 dark:ring-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-indigo-600 dark:focus:ring-indigo-400'
25
+ : 'ring-line-strong text-fg placeholder-fg-subtle focus:ring-accent'
26
26
  const disabledClasses = disabled
27
- ? 'opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-800'
27
+ ? 'opacity-50 cursor-not-allowed bg-surface'
28
28
  : readonly
29
- ? 'bg-gray-50 dark:bg-gray-800 cursor-default'
29
+ ? 'bg-surface cursor-default'
30
30
  : 'bg-white dark:bg-blue-gray-700'
31
31
  const paddingClasses = leftIcon ? 'pl-10' : rightIcon || clearable ? 'pr-10' : ''
32
32
 
33
33
  export const inputClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses} ${paddingClasses} ${inputClassName}`.trim()
34
- export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-900 dark:text-gray-100'}`.trim()
35
- export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
34
+ export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-danger' : 'text-fg'}`.trim()
35
+ export const helperClasses = `mt-2 text-sm ${error ? 'text-danger' : 'text-fg-soft'}`.trim()
36
36
  export const iconClasses = iconSizeClasses[size]
37
37
  export const inputId = `input-${label}`
38
38
  </script>
@@ -74,7 +74,7 @@ defineExpose({ value: inputValue, clear: onClear })
74
74
  <div class="relative">
75
75
  @if(leftIcon)
76
76
  <div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
77
- <span class="{{ iconClasses }} text-gray-400 dark:text-gray-500">{!! leftIcon !!}</span>
77
+ <span class="{{ iconClasses }} text-fg-subtle">{!! leftIcon !!}</span>
78
78
  </div>
79
79
  @endif
80
80
 
@@ -98,7 +98,7 @@ defineExpose({ value: inputValue, clear: onClear })
98
98
  <button
99
99
  type="button"
100
100
  @click="onClear()"
101
- class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 focus:outline-none"
101
+ class="text-fg-subtle hover:text-fg-muted focus:outline-none"
102
102
  aria-label="Clear input"
103
103
  >
104
104
  <svg class="{{ iconClasses }}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
@@ -109,7 +109,7 @@ defineExpose({ value: inputValue, clear: onClear })
109
109
  @endif
110
110
  @if(rightIcon && !clearable)
111
111
  <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
112
- <span class="{{ iconClasses }} text-gray-400 dark:text-gray-500">{!! rightIcon !!}</span>
112
+ <span class="{{ iconClasses }} text-fg-subtle">{!! rightIcon !!}</span>
113
113
  </div>
114
114
  @endif
115
115
  </div>
@@ -125,7 +125,7 @@ defineExpose({ value: inputValue, clear: onClear })
125
125
  @endif
126
126
 
127
127
  @if(showCount && maxLength)
128
- <p class="text-sm text-gray-500 dark:text-gray-400" x-text="charCount()"></p>
128
+ <p class="text-sm text-fg-soft" x-text="charCount()"></p>
129
129
  @endif
130
130
  </div>
131
131
  @endif
@@ -4,7 +4,7 @@ export const disabled = $props.disabled || false
4
4
  export const className = $props.className || ''
5
5
  export const as = $props.as || 'li'
6
6
 
7
- const baseClasses = 'relative cursor-pointer select-none py-2 pl-10 pr-4 text-neutral-900 dark:text-neutral-100 hover:bg-blue-100 dark:hover:bg-blue-900'
7
+ const baseClasses = 'relative cursor-pointer select-none py-2 pl-10 pr-4 text-fg hover:bg-blue-100 dark:hover:bg-blue-900'
8
8
  const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''
9
9
  export const optionClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
10
10
  export const valueJson = JSON.stringify(value === undefined ? null : value)
@@ -32,7 +32,7 @@ function onClick(event) {
32
32
  @if(disabled)aria-disabled="true"@endif
33
33
  @click="onClick($event)"
34
34
  >
35
- <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-blue-600 dark:text-blue-400" data-stx-listbox-check>
35
+ <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-info" data-stx-listbox-check>
36
36
  <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
37
37
  <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
38
38
  </svg>
@@ -35,23 +35,23 @@ function getItemClasses(item) {
35
35
  let cls = sizeClasses[size] || sizeClasses.md
36
36
  if (variant === 'default') {
37
37
  cls += isActiveItem
38
- ? ' text-gray-900 dark:text-gray-100 font-medium'
39
- : ' text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
38
+ ? 'text-fg font-medium'
39
+ : 'text-fg-muted hover:text-fg'
40
40
  }
41
41
  else if (variant === 'pills') {
42
42
  cls += isActiveItem
43
43
  ? ' bg-blue-600 text-white font-medium rounded-full'
44
- : ' text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full'
44
+ : 'text-fg-strong hover:bg-surface-raised rounded-full'
45
45
  }
46
46
  else if (variant === 'underline') {
47
47
  cls += isActiveItem
48
- ? ' text-blue-600 dark:text-blue-400 font-medium border-b-2 border-blue-600 dark:border-blue-400'
49
- : ' text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 border-b-2 border-transparent'
48
+ ? 'text-info font-medium border-b-2 border-info'
49
+ : 'text-fg-muted hover:text-fg border-b-2 border-transparent'
50
50
  }
51
51
  else if (variant === 'sidebar') {
52
52
  cls += isActiveItem
53
- ? ' bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-medium border-l-4 border-blue-600 dark:border-blue-400'
54
- : ' text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 border-l-4 border-transparent'
53
+ ? 'bg-blue-50 dark:bg-blue-900/20 text-info font-medium border-l-4 border-info'
54
+ : 'text-fg-strong hover:bg-surface-raised border-l-4 border-transparent'
55
55
  }
56
56
  cls += ' transition-all duration-200 cursor-pointer flex items-center gap-2'
57
57
  if (item.disabled) cls += ' opacity-50 cursor-not-allowed pointer-events-none'
@@ -74,8 +74,8 @@ defineExpose({ activeKey })
74
74
  <nav class="{{ containerClasses }} {{ gapClasses }}" role="navigation" aria-label="Main navigation">
75
75
  @foreach(item in items)
76
76
  @if(item.href)
77
- <a
78
- href="{{ item.href }}"
77
+ <StxLink
78
+ to="{{ item.href }}"
79
79
  :class="getItemClasses({{ JSON.stringify(item) }})"
80
80
  @click="onClickItem({{ JSON.stringify(item) }}, $event)"
81
81
  :aria-current="isActive({{ JSON.stringify(item) }}) ? 'page' : null"
@@ -86,11 +86,11 @@ defineExpose({ activeKey })
86
86
  @endif
87
87
  <span>{{ item.label }}</span>
88
88
  @if(item.badge)
89
- <span class="ml-auto px-2 py-0.5 text-xs font-semibold rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300">
89
+ <span class="ml-auto px-2 py-0.5 text-xs font-semibold rounded-full bg-surface-sunken text-fg-strong">
90
90
  {{ item.badge }}
91
91
  </span>
92
92
  @endif
93
- </a>
93
+ </StxLink>
94
94
  @else
95
95
  <button
96
96
  type="button"
@@ -103,7 +103,7 @@ defineExpose({ activeKey })
103
103
  @endif
104
104
  <span>{{ item.label }}</span>
105
105
  @if(item.badge)
106
- <span class="ml-auto px-2 py-0.5 text-xs font-semibold rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300">
106
+ <span class="ml-auto px-2 py-0.5 text-xs font-semibold rounded-full bg-surface-sunken text-fg-strong">
107
107
  {{ item.badge }}
108
108
  </span>
109
109
  @endif
@@ -7,9 +7,9 @@ export const showPrevNext = $props.showPrevNext ?? true
7
7
  export const className = $props.className || ''
8
8
 
9
9
  export const paginationClasses = `flex items-center gap-1 ${className}`.trim()
10
- export const buttonClasses = `px-3 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-white dark:disabled:hover:bg-gray-800 transition-colors duration-150`.trim()
11
- export const activeButtonClasses = `px-3 py-2 text-sm font-medium text-white bg-blue-600 dark:bg-blue-500 border border-blue-600 dark:border-blue-500 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900`.trim()
12
- export const ellipsisClasses = `px-3 py-2 text-sm font-medium text-gray-400 dark:text-gray-600`.trim()
10
+ export const buttonClasses = `px-3 py-2 text-sm font-medium text-fg-strong bg-white dark:bg-gray-800 border border-line-strong rounded-md hover:bg-surface focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-white dark:disabled:hover:bg-gray-800 transition-colors duration-150`.trim()
11
+ export const activeButtonClasses = `px-3 py-2 text-sm font-medium text-white bg-info-solid border border-info rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900`.trim()
12
+ export const ellipsisClasses = `px-3 py-2 text-sm font-medium text-fg-subtle`.trim()
13
13
  export const iconClasses = `w-5 h-5`.trim()
14
14
  </script>
15
15
 
@@ -24,7 +24,7 @@ export const isOneTime = mode === 'one-time'
24
24
 
25
25
  @if(isOneTime)
26
26
  <div class="p-8 text-center">
27
- <p class="text-gray-600 dark:text-gray-400">
27
+ <p class="text-fg-muted">
28
28
  One-time payment mode is not yet implemented.
29
29
  </p>
30
30
  </div>
@@ -15,33 +15,33 @@ export const containerClasses = `mt-16 w-2/3 bg-white dark:bg-blue-gray-800 px-8
15
15
  </script>
16
16
 
17
17
  <div class="{{ containerClasses }}">
18
- <h2 class="text-lg text-gray-900 dark:text-gray-100 font-medium">
18
+ <h2 class="text-lg text-fg font-medium">
19
19
  Payment Info
20
20
  </h2>
21
21
 
22
22
  @if(isLoading)
23
23
  <!-- Loading skeleton -->
24
24
  <div class="mt-8 animate-pulse">
25
- <div class="h-20 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
25
+ <div class="h-20 bg-surface-sunken rounded-lg"></div>
26
26
  </div>
27
27
  @else
28
28
  @if(paymentMethod)
29
- <div class="col-span-1 mt-8 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-blue-gray-800 shadow divide-y divide-gray-200 dark:divide-gray-700">
29
+ <div class="col-span-1 mt-8 border border-line rounded-lg bg-white dark:bg-blue-gray-800 shadow divide-y divide-line">
30
30
  <div class="w-full p-3">
31
31
  <div class="flex items-center justify-between">
32
32
  <div class="flex items-center space-x-4">
33
33
  <!-- Card Brand Icon -->
34
- <div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-gray-100 dark:bg-gray-700 rounded-md">
34
+ <div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-surface-raised rounded-md">
35
35
  <span class="text-2xl">{{ brandIcons[paymentMethod.brand.toLowerCase()] || brandIcons.default }}</span>
36
36
  </div>
37
37
 
38
38
  <!-- Card Details -->
39
39
  <div>
40
- <h2 class="text-sm text-gray-600 dark:text-gray-300">
40
+ <h2 class="text-sm text-fg-muted">
41
41
  {{ paymentMethod.brand }} •••• {{ paymentMethod.last_four }}
42
42
  <span class="ml-4 inline-flex items-center rounded-md bg-indigo-50 dark:bg-indigo-900/30 px-2 py-1 text-xs text-indigo-700 dark:text-indigo-300 font-medium ring-1 ring-indigo-700/10 dark:ring-indigo-300/20 ring-inset">Default</span>
43
43
  <br>
44
- <span class="text-xs text-gray-500 dark:text-gray-400 italic">Expires {{ paymentMethod.exp_month }} / {{ paymentMethod.exp_year }}</span>
44
+ <span class="text-xs text-fg-soft italic">Expires {{ paymentMethod.exp_month }} / {{ paymentMethod.exp_year }}</span>
45
45
  </h2>
46
46
  </div>
47
47
  </div>
@@ -50,9 +50,9 @@ export const containerClasses = `mt-16 w-2/3 bg-white dark:bg-blue-gray-800 px-8
50
50
  </div>
51
51
  @else
52
52
  <!-- Empty state -->
53
- <div class="col-span-1 mt-8 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-blue-gray-800 shadow divide-y divide-gray-200 dark:divide-gray-700">
53
+ <div class="col-span-1 mt-8 border border-line rounded-lg bg-white dark:bg-blue-gray-800 shadow divide-y divide-line">
54
54
  <div class="w-full px-4 py-5">
55
- <h2 class="text-center text-sm text-gray-600 dark:text-gray-300">
55
+ <h2 class="text-center text-sm text-fg-muted">
56
56
  You haven't added any payment methods yet.
57
57
  </h2>
58
58
  </div>
@@ -33,25 +33,25 @@ function onDelete(methodId) {
33
33
  <div class="{{ containerClasses }}">
34
34
  @if(isLoading)
35
35
  <div class="animate-pulse">
36
- <div class="h-24 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
36
+ <div class="h-24 bg-surface-sunken rounded-lg"></div>
37
37
  </div>
38
38
  @else
39
39
  @if(paymentMethods.length > 0)
40
40
  <ul role="list" class="grid grid-cols-1 gap-6 lg:grid-cols-1 sm:grid-cols-1">
41
41
  @foreach(method in paymentMethods)
42
- <li class="col-span-1 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-blue-gray-800 shadow divide-y divide-gray-200 dark:divide-gray-700">
42
+ <li class="col-span-1 border border-line rounded-lg bg-white dark:bg-blue-gray-800 shadow divide-y divide-line">
43
43
  <div class="w-full p-3">
44
44
  <div class="flex items-center justify-between">
45
45
  <div class="flex items-center space-x-4">
46
- <div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-gray-100 dark:bg-gray-700 rounded-md">
46
+ <div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-surface-raised rounded-md">
47
47
  <span class="text-2xl">{{ brandIcons[method.brand.toLowerCase()] || brandIcons.default }}</span>
48
48
  </div>
49
49
 
50
50
  <div>
51
- <h2 class="text-sm text-gray-600 dark:text-gray-300">
51
+ <h2 class="text-sm text-fg-muted">
52
52
  {{ method.brand }} •••• {{ method.last_four }}
53
53
  </h2>
54
- <span class="text-xs text-gray-500 dark:text-gray-400 italic">
54
+ <span class="text-xs text-fg-soft italic">
55
55
  Expires {{ method.exp_month }} / {{ method.exp_year }}
56
56
  </span>
57
57
  </div>
@@ -61,7 +61,7 @@ function onDelete(methodId) {
61
61
  @if(showMakeDefault)
62
62
  <button
63
63
  type="button"
64
- class="border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-blue-gray-700 px-2 py-1 text-sm text-gray-700 dark:text-gray-300 font-semibold shadow-sm hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
64
+ class="border border-line-strong rounded-md bg-white dark:bg-blue-gray-700 px-2 py-1 text-sm text-fg-strong font-semibold shadow-sm hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
65
65
  @click="onMakeDefault('{{ method.id }}')"
66
66
  title="Make default"
67
67
  >
@@ -74,7 +74,7 @@ function onDelete(methodId) {
74
74
  @if(showDelete)
75
75
  <button
76
76
  type="button"
77
- class="border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-blue-gray-700 px-2 py-1 text-sm text-red-600 dark:text-red-400 font-semibold shadow-sm hover:bg-red-50 dark:hover:bg-red-900/20 focus-visible:outline-2 focus-visible:outline-red-600 focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
77
+ class="border border-line-strong rounded-md bg-white dark:bg-blue-gray-700 px-2 py-1 text-sm text-danger font-semibold shadow-sm hover:bg-red-50 dark:hover:bg-red-900/20 focus-visible:outline-2 focus-visible:outline-red-600 focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
78
78
  @click="onDelete('{{ method.id }}')"
79
79
  title="Delete payment method"
80
80
  >
@@ -90,12 +90,12 @@ function onDelete(methodId) {
90
90
  @endforeach
91
91
  </ul>
92
92
  @else
93
- <div class="text-center py-12 bg-white dark:bg-blue-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
94
- <svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
93
+ <div class="text-center py-12 bg-white dark:bg-blue-gray-800 rounded-lg border border-line">
94
+ <svg class="mx-auto h-12 w-12 text-fg-subtle" fill="none" viewBox="0 0 24 24" stroke="currentColor">
95
95
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
96
96
  </svg>
97
- <h3 class="mt-2 text-sm text-gray-900 dark:text-gray-100 font-medium">No payment methods</h3>
98
- <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
97
+ <h3 class="mt-2 text-sm text-fg font-medium">No payment methods</h3>
98
+ <p class="mt-1 text-sm text-fg-soft">
99
99
  You haven't added any payment methods yet.
100
100
  </p>
101
101
  </div>
@@ -115,12 +115,12 @@ onMount(() => initializeStripe())
115
115
  <div>
116
116
  <!-- Contact Information -->
117
117
  <div>
118
- <h2 class="text-lg text-gray-900 dark:text-gray-100 font-medium">
118
+ <h2 class="text-lg text-fg font-medium">
119
119
  Contact information
120
120
  </h2>
121
121
 
122
122
  <div class="mt-4">
123
- <label for="email-address" class="block text-sm text-gray-700 dark:text-gray-300 font-medium">
123
+ <label for="email-address" class="block text-sm text-fg-strong font-medium">
124
124
  Email address
125
125
  </label>
126
126
  <div class="mt-1">
@@ -130,21 +130,21 @@ onMount(() => initializeStripe())
130
130
  name="email-address"
131
131
  autocomplete="email"
132
132
  required
133
- class="block w-full border border-gray-300 dark:border-gray-600 rounded-md p-2 shadow-sm bg-white dark:bg-blue-gray-700 text-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 sm:text-sm focus:ring-indigo-500 dark:focus:ring-indigo-400"
133
+ class="block w-full border border-line-strong rounded-md p-2 shadow-sm bg-white dark:bg-blue-gray-700 text-fg focus:border-indigo-500 dark:focus:border-indigo-400 sm:text-sm focus:ring-indigo-500 dark:focus:ring-indigo-400"
134
134
  />
135
135
  </div>
136
136
  </div>
137
137
  </div>
138
138
 
139
139
  <!-- Billing Information -->
140
- <div class="mt-10 border-t border-gray-200 dark:border-gray-700 pt-10">
141
- <h2 class="text-lg text-gray-900 dark:text-gray-100 font-medium">
140
+ <div class="mt-10 border-t border-line pt-10">
141
+ <h2 class="text-lg text-fg font-medium">
142
142
  Billing information
143
143
  </h2>
144
144
 
145
145
  <div class="mt-4 grid grid-cols-1 gap-y-6 sm:grid-cols-2 sm:gap-x-4">
146
146
  <div class="sm:col-span-2">
147
- <label for="card-name" class="block text-sm text-gray-700 dark:text-gray-300 font-medium">
147
+ <label for="card-name" class="block text-sm text-fg-strong font-medium">
148
148
  Name on card
149
149
  </label>
150
150
  <div class="mt-1">
@@ -154,21 +154,21 @@ onMount(() => initializeStripe())
154
154
  name="card-name"
155
155
  autocomplete="cc-name"
156
156
  required
157
- class="block w-full border border-gray-300 dark:border-gray-600 rounded-md p-2 shadow-sm bg-white dark:bg-blue-gray-700 text-gray-900 dark:text-gray-100 focus:border-indigo-500 sm:text-sm focus:ring-indigo-500"
157
+ class="block w-full border border-line-strong rounded-md p-2 shadow-sm bg-white dark:bg-blue-gray-700 text-fg focus:border-indigo-500 sm:text-sm focus:ring-indigo-500"
158
158
  />
159
159
  </div>
160
160
  </div>
161
161
 
162
162
  <!-- Stripe Element Mount Point -->
163
163
  <div class="sm:col-span-2">
164
- <div id="payment-element" class="mt-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-blue-gray-700 p-3"></div>
164
+ <div id="payment-element" class="mt-2 border border-line-strong rounded-md bg-white dark:bg-blue-gray-700 p-3"></div>
165
165
  </div>
166
166
  </div>
167
167
  </div>
168
168
 
169
169
  <!-- Payment Type -->
170
- <div class="mt-10 border-t border-gray-200 dark:border-gray-700 pt-10">
171
- <h2 class="text-lg text-gray-900 dark:text-gray-100 font-medium">
170
+ <div class="mt-10 border-t border-line pt-10">
171
+ <h2 class="text-lg text-fg font-medium">
172
172
  Payment
173
173
  </h2>
174
174
 
@@ -181,9 +181,9 @@ onMount(() => initializeStripe())
181
181
  name="payment-type"
182
182
  type="radio"
183
183
  checked
184
- class="h-4 w-4 border-gray-300 dark:border-gray-600 text-indigo-600 dark:text-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400"
184
+ class="h-4 w-4 border-line-strong text-accent focus:ring-indigo-500 dark:focus:ring-indigo-400"
185
185
  />
186
- <label for="credit-card" class="ml-3 block text-sm text-gray-700 dark:text-gray-300 font-medium">
186
+ <label for="credit-card" class="ml-3 block text-sm text-fg-strong font-medium">
187
187
  Credit card
188
188
  </label>
189
189
  </div>
@@ -194,22 +194,22 @@ onMount(() => initializeStripe())
194
194
 
195
195
  <!-- Right Column - Order Summary -->
196
196
  <div class="mt-10 lg:mt-0">
197
- <h2 class="text-lg text-gray-900 dark:text-gray-100 font-medium">
197
+ <h2 class="text-lg text-fg font-medium">
198
198
  Order summary
199
199
  </h2>
200
200
 
201
- <div class="mt-4 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-blue-gray-800 shadow-sm">
201
+ <div class="mt-4 border border-line rounded-lg bg-white dark:bg-blue-gray-800 shadow-sm">
202
202
  <h3 class="sr-only">Items in your cart</h3>
203
203
 
204
204
  <!-- Product List -->
205
- <ul role="list" class="divide-y divide-gray-200 dark:divide-gray-700">
205
+ <ul role="list" class="divide-y divide-line">
206
206
  @foreach(product in products)
207
207
  <li class="flex px-4 py-6 sm:px-6">
208
208
  <div class="flex-shrink-0">
209
209
  @if(product.images)
210
210
  <img src="{{ product.images }}" alt="{{ product.name }}" class="w-20 rounded-md" />
211
211
  @else
212
- <div class="w-20 h-20 bg-gray-200 dark:bg-gray-700 rounded-md flex items-center justify-center">
212
+ <div class="w-20 h-20 bg-surface-sunken rounded-md flex items-center justify-center">
213
213
  <svg class="h-8 w-8 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
214
214
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
215
215
  </svg>
@@ -221,9 +221,15 @@ onMount(() => initializeStripe())
221
221
  <div class="flex">
222
222
  <div class="min-w-0 flex-1">
223
223
  <h4 class="text-sm">
224
- <a href="#" class="text-gray-700 dark:text-gray-300 font-medium hover:text-gray-800 dark:hover:text-gray-200">
225
- {{ product.name }}
226
- </a>
224
+ @if(product.href)
225
+ <StxLink to="{{ product.href }}" class="text-fg-strong font-medium hover:text-gray-800 dark:hover:text-gray-200">
226
+ {{ product.name }}
227
+ </StxLink>
228
+ @else
229
+ <span class="text-fg-strong font-medium">
230
+ {{ product.name }}
231
+ </span>
232
+ @endif
227
233
  </h4>
228
234
  </div>
229
235
 
@@ -231,7 +237,7 @@ onMount(() => initializeStripe())
231
237
  <div class="ml-4 flow-root flex-shrink-0">
232
238
  <button
233
239
  type="button"
234
- class="flex items-center justify-center bg-white dark:bg-blue-gray-700 p-2.5 text-gray-400 dark:text-gray-500 -m-2.5 hover:text-gray-500 dark:hover:text-gray-400"
240
+ class="flex items-center justify-center bg-white dark:bg-blue-gray-700 p-2.5 text-fg-subtle -m-2.5 hover:text-fg-soft"
235
241
  @click="onRemoveProduct('{{ product.id }}')"
236
242
  title="Remove"
237
243
  >
@@ -245,7 +251,7 @@ onMount(() => initializeStripe())
245
251
  </div>
246
252
 
247
253
  <div class="flex flex-1 items-end justify-between pt-2">
248
- <p class="mt-1 text-sm text-gray-900 dark:text-gray-100 font-medium">
254
+ <p class="mt-1 text-sm text-fg font-medium">
249
255
  ${{ (product.price / 100).toFixed(2) }}
250
256
  </p>
251
257
 
@@ -254,7 +260,7 @@ onMount(() => initializeStripe())
254
260
  <select
255
261
  id="quantity-{{ product.id }}"
256
262
  name="quantity"
257
- class="border border-gray-300 dark:border-gray-600 rounded-md text-left text-base text-gray-700 dark:text-gray-300 font-medium shadow-sm bg-white dark:bg-blue-gray-700 focus:border-indigo-500 sm:text-sm focus:outline-none focus:ring-1 focus:ring-indigo-500"
263
+ class="border border-line-strong rounded-md text-left text-base text-fg-strong font-medium shadow-sm bg-white dark:bg-blue-gray-700 focus:border-indigo-500 sm:text-sm focus:outline-none focus:ring-1 focus:ring-indigo-500"
258
264
  >
259
265
  <option value="1" {{ (product.quantity || 1) === 1 ? 'selected' : '' }}>1</option>
260
266
  <option value="2" {{ (product.quantity || 1) === 2 ? 'selected' : '' }}>2</option>
@@ -273,18 +279,18 @@ onMount(() => initializeStripe())
273
279
  </ul>
274
280
 
275
281
  <!-- Summary Totals -->
276
- <dl class="border-t border-gray-200 dark:border-gray-700 px-4 py-6 space-y-6 sm:px-6">
282
+ <dl class="border-t border-line px-4 py-6 space-y-6 sm:px-6">
277
283
  <div class="flex items-center justify-between">
278
- <dt class="text-sm text-gray-600 dark:text-gray-400">Subtotal</dt>
279
- <dd class="text-sm text-gray-900 dark:text-gray-100 font-medium">
284
+ <dt class="text-sm text-fg-muted">Subtotal</dt>
285
+ <dd class="text-sm text-fg font-medium">
280
286
  ${{ (subtotal / 100).toFixed(2) }}
281
287
  </dd>
282
288
  </div>
283
289
 
284
290
  @if(shipping > 0)
285
291
  <div class="flex items-center justify-between">
286
- <dt class="text-sm text-gray-600 dark:text-gray-400">Shipping</dt>
287
- <dd class="text-sm text-gray-900 dark:text-gray-100 font-medium">
292
+ <dt class="text-sm text-fg-muted">Shipping</dt>
293
+ <dd class="text-sm text-fg font-medium">
288
294
  ${{ (shipping / 100).toFixed(2) }}
289
295
  </dd>
290
296
  </div>
@@ -292,26 +298,26 @@ onMount(() => initializeStripe())
292
298
 
293
299
  @if(taxes > 0)
294
300
  <div class="flex items-center justify-between">
295
- <dt class="text-sm text-gray-600 dark:text-gray-400">Taxes</dt>
296
- <dd class="text-sm text-gray-900 dark:text-gray-100 font-medium">
301
+ <dt class="text-sm text-fg-muted">Taxes</dt>
302
+ <dd class="text-sm text-fg font-medium">
297
303
  ${{ (taxes / 100).toFixed(2) }}
298
304
  </dd>
299
305
  </div>
300
306
  @endif
301
307
 
302
- <div class="flex items-center justify-between border-t border-gray-200 dark:border-gray-700 pt-6">
303
- <dt class="text-base text-gray-900 dark:text-gray-100 font-medium">Total</dt>
304
- <dd class="text-base text-gray-900 dark:text-gray-100 font-medium">
308
+ <div class="flex items-center justify-between border-t border-line pt-6">
309
+ <dt class="text-base text-fg font-medium">Total</dt>
310
+ <dd class="text-base text-fg font-medium">
305
311
  ${{ (total / 100).toFixed(2) }}
306
312
  </dd>
307
313
  </div>
308
314
  </dl>
309
315
 
310
316
  <!-- Submit Button -->
311
- <div class="border-t border-gray-200 dark:border-gray-700 px-4 py-6 sm:px-6">
317
+ <div class="border-t border-line px-4 py-6 sm:px-6">
312
318
  <button
313
319
  type="submit"
314
- class="w-full border border-transparent rounded-md bg-indigo-600 dark:bg-indigo-500 px-4 py-3 text-base text-white font-medium shadow-sm hover:bg-indigo-700 dark:hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900"
320
+ class="w-full border border-transparent rounded-md bg-accent-solid px-4 py-3 text-base text-white font-medium shadow-sm hover:bg-indigo-700 dark:hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900"
315
321
  >
316
322
  Confirm order
317
323
  </button>
@@ -11,11 +11,11 @@ export const className = $props.className || ''
11
11
  const linearSizeClasses = { sm: 'h-1', md: 'h-2', lg: 'h-3' }
12
12
  const circularSizeClasses = { sm: 'w-12 h-12', md: 'w-16 h-16', lg: 'w-24 h-24' }
13
13
  const colorClasses = {
14
- primary: 'bg-blue-600 dark:bg-blue-500',
14
+ primary: 'bg-info-solid',
15
15
  secondary: 'bg-purple-600 dark:bg-purple-500',
16
- success: 'bg-green-600 dark:bg-green-500',
16
+ success: 'bg-success-solid',
17
17
  warning: 'bg-yellow-600 dark:bg-yellow-500',
18
- danger: 'bg-red-600 dark:bg-red-500',
18
+ danger: 'bg-danger-solid',
19
19
  info: 'bg-cyan-600 dark:bg-cyan-500',
20
20
  }
21
21
 
@@ -28,16 +28,16 @@ export const containerClasses = variant === 'linear'
28
28
  ? `w-full ${className}`.trim()
29
29
  : `inline-flex items-center justify-center ${className}`.trim()
30
30
 
31
- export const linearTrackClasses = `w-full ${linearSizeClasses[size]} bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden`.trim()
31
+ export const linearTrackClasses = `w-full ${linearSizeClasses[size]} bg-surface-sunken rounded-full overflow-hidden`.trim()
32
32
  export const linearBarClasses = `h-full ${colorClasses[color]} transition-all duration-300 ease-in-out ${indeterminate ? 'animate-progress-indeterminate' : ''}`.trim()
33
33
  export const circularSizeClass = circularSizeClasses[size]
34
- export const labelClasses = `text-sm font-medium text-gray-700 dark:text-gray-300 mb-2`.trim()
34
+ export const labelClasses = `text-sm font-medium text-fg-strong mb-2`.trim()
35
35
  export const circularTrackColor = 'stroke-gray-200 dark:stroke-gray-700'
36
- export const circularBarColor = color === 'primary' ? 'stroke-blue-600 dark:stroke-blue-500'
36
+ export const circularBarColor = color === 'primary' ? 'stroke-info'
37
37
  : color === 'secondary' ? 'stroke-purple-600 dark:stroke-purple-500'
38
- : color === 'success' ? 'stroke-green-600 dark:stroke-green-500'
38
+ : color === 'success' ? 'stroke-success'
39
39
  : color === 'warning' ? 'stroke-yellow-600 dark:stroke-yellow-500'
40
- : color === 'danger' ? 'stroke-red-600 dark:stroke-red-500'
40
+ : color === 'danger' ? 'stroke-danger'
41
41
  : 'stroke-cyan-600 dark:stroke-cyan-500'
42
42
  </script>
43
43
 
@@ -112,7 +112,7 @@ defineExpose({ value, setValue: (v) => value.set(v) })
112
112
 
113
113
  @if(showLabel)
114
114
  <div class="absolute inset-0 flex items-center justify-center">
115
- <span class="text-sm font-semibold text-gray-700 dark:text-gray-300" x-text="percentLabel()"></span>
115
+ <span class="text-sm font-semibold text-fg-strong" x-text="percentLabel()"></span>
116
116
  </div>
117
117
  @endif
118
118
  </div>
@@ -11,13 +11,13 @@ export const name = $props.name || ''
11
11
  export const className = $props.className || ''
12
12
 
13
13
  const sizeClasses = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6' }
14
- const baseClasses = 'border-gray-300 dark:border-gray-600 text-indigo-600 dark:text-indigo-500 focus:ring-indigo-600 dark:focus:ring-indigo-500 focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 transition-colors'
15
- const stateClasses = error ? 'border-red-300 dark:border-red-600 text-red-600 dark:text-red-500 focus:ring-red-500 dark:focus:ring-red-400' : ''
14
+ const baseClasses = 'border-line-strong text-accent focus:ring-accent focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 transition-colors'
15
+ const stateClasses = error ? 'border-red-300 dark:border-red-600 text-danger focus:ring-red-500 dark:focus:ring-red-400' : ''
16
16
  const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'
17
17
 
18
18
  export const radioClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses}`.trim()
19
- export const labelClasses = `text-sm font-medium ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-900 dark:text-gray-100'} ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`.trim()
20
- export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
19
+ export const labelClasses = `text-sm font-medium ${error ? 'text-danger' : 'text-fg'} ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`.trim()
20
+ export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-fg-soft'}`.trim()
21
21
  export const inputId = `radio-${value || label}`
22
22
  </script>
23
23