@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
@@ -16,19 +16,19 @@ const sizeClasses = {
16
16
 
17
17
  // Color classes
18
18
  const colorClasses = {
19
- primary: 'text-blue-600 dark:text-blue-500',
19
+ primary: 'text-info',
20
20
  secondary: 'text-purple-600 dark:text-purple-500',
21
- success: 'text-green-600 dark:text-green-500',
21
+ success: 'text-success',
22
22
  warning: 'text-yellow-600 dark:text-yellow-500',
23
- danger: 'text-red-600 dark:text-red-500',
23
+ danger: 'text-danger',
24
24
  info: 'text-cyan-600 dark:text-cyan-500',
25
25
  white: 'text-white',
26
- gray: 'text-gray-600 dark:text-gray-400',
26
+ gray: 'text-fg-muted',
27
27
  }
28
28
 
29
29
  export const containerClasses = `inline-flex flex-col items-center gap-2 ${className}`.trim()
30
30
  export const spinnerClasses = `${sizeClasses[size]} ${colorClasses[color]} animate-spin`.trim()
31
- export const labelClasses = `text-sm font-medium text-gray-700 dark:text-gray-300`.trim()
31
+ export const labelClasses = `text-sm font-medium text-fg-strong`.trim()
32
32
 
33
33
  // Dots size classes
34
34
  const dotsSizeClasses = {
@@ -40,11 +40,11 @@ const dotsSizeClasses = {
40
40
  }
41
41
 
42
42
  const dotsColorClasses = {
43
- primary: 'bg-blue-600 dark:bg-blue-500',
43
+ primary: 'bg-info-solid',
44
44
  secondary: 'bg-purple-600 dark:bg-purple-500',
45
- success: 'bg-green-600 dark:bg-green-500',
45
+ success: 'bg-success-solid',
46
46
  warning: 'bg-yellow-600 dark:bg-yellow-500',
47
- danger: 'bg-red-600 dark:bg-red-500',
47
+ danger: 'bg-danger-solid',
48
48
  info: 'bg-cyan-600 dark:bg-cyan-500',
49
49
  white: 'bg-white',
50
50
  gray: 'bg-gray-600 dark:bg-gray-400',
@@ -29,7 +29,7 @@ function onClick() {
29
29
  @click="onClick()"
30
30
  class="flex items-center gap-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 rounded-lg p-2"
31
31
  >
32
- <div class="{{ isComplete ? 'bg-blue-600 dark:bg-blue-500' : isCurrent ? 'bg-blue-600 dark:bg-blue-500 ring-4 ring-blue-200 dark:ring-blue-800' : 'bg-neutral-300 dark:bg-neutral-600' }} w-10 h-10 rounded-full flex items-center justify-center text-white font-semibold transition-all">
32
+ <div class="{{ isComplete ? 'bg-info-solid' : isCurrent ? 'bg-info-solid ring-4 ring-blue-200 dark:ring-blue-800' : 'bg-neutral-300 dark:bg-neutral-600' }} w-10 h-10 rounded-full flex items-center justify-center text-white font-semibold transition-all">
33
33
  @if(isComplete)
34
34
  <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
35
35
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
@@ -41,11 +41,11 @@ function onClick() {
41
41
 
42
42
  @if(label)
43
43
  <div class="text-left">
44
- <div class="text-sm font-medium {{ isCurrent ? 'text-blue-600 dark:text-blue-400' : 'text-neutral-900 dark:text-white' }}">
44
+ <div class="text-sm font-medium {{ isCurrent ? 'text-info' : 'text-neutral-900 dark:text-white' }}">
45
45
  {{ label }}
46
46
  </div>
47
47
  @if(description)
48
- <div class="text-xs text-neutral-500 dark:text-neutral-400">
48
+ <div class="text-xs text-fg-soft">
49
49
  {{ description }}
50
50
  </div>
51
51
  @endif
@@ -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>
@@ -53,7 +53,7 @@ defineExpose({ isChecked, toggle })
53
53
 
54
54
  <label class="inline-flex items-center gap-3 cursor-pointer">
55
55
  @if(label)
56
- <span class="text-sm font-medium text-neutral-700 dark:text-neutral-300">
56
+ <span class="text-sm font-medium text-fg-strong">
57
57
  {{ label }}
58
58
  </span>
59
59
  @endif
@@ -3,7 +3,7 @@ export const className = $props.className || ''
3
3
  export const striped = $props.striped || false
4
4
  export const hoverable = $props.hoverable !== false
5
5
 
6
- const baseClasses = 'min-w-full divide-y divide-neutral-200 dark:divide-neutral-700'
6
+ const baseClasses = 'min-w-full divide-y divide-line'
7
7
  const tableClasses = `${baseClasses} ${className}`.trim()
8
8
  </script>
9
9
 
@@ -1,7 +1,7 @@
1
1
  <script server>
2
2
  export const className = $props.className || ''
3
3
 
4
- const baseClasses = 'bg-white divide-y divide-neutral-200 dark:bg-neutral-900 dark:divide-neutral-700'
4
+ const baseClasses = 'bg-white divide-y divide-line dark:bg-neutral-900'
5
5
  const bodyClasses = `${baseClasses} ${className}`.trim()
6
6
  </script>
7
7
 
@@ -1,7 +1,7 @@
1
1
  <script server>
2
2
  export const className = $props.className || ''
3
3
 
4
- const baseClasses = 'px-6 py-4 whitespace-nowrap text-sm text-neutral-900 dark:text-neutral-100'
4
+ const baseClasses = 'px-6 py-4 whitespace-nowrap text-sm text-fg'
5
5
  const cellClasses = `${baseClasses} ${className}`.trim()
6
6
  </script>
7
7
 
@@ -1,7 +1,7 @@
1
1
  <script server>
2
2
  export const className = $props.className || ''
3
3
 
4
- const baseClasses = 'bg-neutral-50 dark:bg-neutral-800'
4
+ const baseClasses = 'bg-surface'
5
5
  const headClasses = `${baseClasses} ${className}`.trim()
6
6
  </script>
7
7
 
@@ -2,8 +2,8 @@
2
2
  export const className = $props.className || ''
3
3
  export const sortable = $props.sortable || false
4
4
 
5
- const baseClasses = 'px-6 py-3 text-left text-xs font-medium text-neutral-500 uppercase tracking-wider dark:text-neutral-400'
6
- const sortableClasses = sortable ? 'cursor-pointer hover:text-neutral-700 dark:hover:text-neutral-200' : ''
5
+ const baseClasses = 'px-6 py-3 text-left text-xs font-medium text-fg-soft uppercase tracking-wider'
6
+ const sortableClasses = sortable ? 'cursor-pointer hover:text-fg-strong' : ''
7
7
  export const headerClasses = `${baseClasses} ${sortableClasses} ${className}`.trim()
8
8
  </script>
9
9
 
@@ -2,7 +2,7 @@
2
2
  export const className = $props.className || ''
3
3
  export const hoverable = $props.hoverable !== false
4
4
 
5
- const hoverClasses = hoverable ? 'hover:bg-neutral-50 dark:hover:bg-neutral-800' : ''
5
+ const hoverClasses = hoverable ? 'hover:bg-surface' : ''
6
6
  const rowClasses = `${hoverClasses} ${className}`.trim()
7
7
  </script>
8
8
 
@@ -24,9 +24,9 @@ const tabListOrientationClasses = {
24
24
  }
25
25
 
26
26
  const variantClasses = {
27
- line: 'border-gray-200 dark:border-gray-700',
28
- pills: 'gap-2 border-0 bg-gray-100 dark:bg-gray-800 p-1 rounded-lg',
29
- enclosed: 'border-gray-200 dark:border-gray-700',
27
+ line: 'border-line',
28
+ pills: 'gap-2 border-0 bg-surface-raised p-1 rounded-lg',
29
+ enclosed: 'border-line',
30
30
  }
31
31
 
32
32
  export const containerClasses = `flex ${orientationClasses[orientation]} ${className}`.trim()
@@ -97,14 +97,14 @@ function getTabClasses(index) {
97
97
  const base = 'px-4 py-2 font-medium text-sm transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900'
98
98
  if (variant === 'line') {
99
99
  const border = orientation === 'horizontal' ? 'border-b-2' : 'border-r-2'
100
- return `${base} ${border} ${isActiveTab ? 'border-blue-500 text-blue-600 dark:text-blue-400' : 'border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 hover:border-gray-300 dark:hover:border-gray-600'}`
100
+ return `${base} ${border} ${isActiveTab ? 'border-blue-500 text-info' : 'border-transparent text-fg-muted hover:text-fg hover:border-line-strong'}`
101
101
  }
102
102
  if (variant === 'pills') {
103
- return `${base} rounded-md ${isActiveTab ? 'bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 shadow-sm' : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200'}`
103
+ return `${base} rounded-md ${isActiveTab ? 'bg-white dark:bg-gray-700 text-fg shadow-sm' : 'text-fg-muted hover:text-fg'}`
104
104
  }
105
105
  if (variant === 'enclosed') {
106
106
  const borders = orientation === 'horizontal' ? 'border-t border-l border-r rounded-t-md' : 'border-t border-l border-b rounded-l-md'
107
- return `${base} ${borders} ${isActiveTab ? 'bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-700 -mb-px' : 'bg-gray-50 dark:bg-gray-900 border-transparent hover:border-gray-200 dark:hover:border-gray-700'}`
107
+ return `${base} ${borders} ${isActiveTab ? 'bg-white dark:bg-gray-800 border-line -mb-px' : 'bg-surface border-transparent hover:border-line'}`
108
108
  }
109
109
  return base
110
110
  }
@@ -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
@@ -19,16 +19,16 @@ const resizeClasses = { none: 'resize-none', vertical: 'resize-y', horizontal: '
19
19
  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 px-4 py-2 text-base dark:bg-blue-gray-700 dark:text-gray-100'
20
20
  const stateClasses = error
21
21
  ? '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'
22
- : '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'
22
+ : 'ring-line-strong text-fg placeholder-fg-subtle focus:ring-accent'
23
23
  const disabledClasses = disabled
24
- ? 'opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-800'
24
+ ? 'opacity-50 cursor-not-allowed bg-surface'
25
25
  : readonly
26
- ? 'bg-gray-50 dark:bg-gray-800 cursor-default'
26
+ ? 'bg-surface cursor-default'
27
27
  : 'bg-white dark:bg-blue-gray-700'
28
28
 
29
29
  export const textareaClasses = `${baseClasses} ${stateClasses} ${disabledClasses} ${resizeClasses[resize]} ${className}`.trim()
30
- 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()
31
- export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
30
+ export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-danger' : 'text-fg'}`.trim()
31
+ export const helperClasses = `mt-2 text-sm ${error ? 'text-danger' : 'text-fg-soft'}`.trim()
32
32
  </script>
33
33
 
34
34
  <script client>
@@ -101,7 +101,7 @@ defineExpose({ value: inputValue })
101
101
  @endif
102
102
 
103
103
  @if(showCount && maxLength)
104
- <p class="text-sm text-gray-500 dark:text-gray-400" x-text="charCount()"></p>
104
+ <p class="text-sm text-fg-soft" x-text="charCount()"></p>
105
105
  @endif
106
106
  </div>
107
107
  @endif
@@ -56,10 +56,10 @@ function onRecoveryCode(event) {
56
56
  <div class="mx-auto max-w-sm rounded-md px-8 py-4 shadow-md bg-white dark:bg-blue-gray-800">
57
57
  <div class="card-body">
58
58
  <div>
59
- <h3 class="text-center text-sm text-gray-900 dark:text-gray-100 font-semibold">
59
+ <h3 class="text-center text-sm text-fg font-semibold">
60
60
  {{ headingText }}
61
61
  </h3>
62
- <label for="code-0" class="mt-4 block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
62
+ <label for="code-0" class="mt-4 block text-sm text-fg font-medium leading-6">
63
63
  {{ labelText }}
64
64
  </label>
65
65
  <form @submit="onSubmit($event)">
@@ -71,7 +71,7 @@ function onRecoveryCode(event) {
71
71
  maxlength="1"
72
72
  name="code-{{ i }}"
73
73
  placeholder="-"
74
- class="block w-full border-0 rounded-md px-2 py-2 text-center text-gray-900 dark:text-gray-100 ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-indigo-600 focus:ring-inset dark:bg-blue-gray-700"
74
+ class="block w-full border-0 rounded-md px-2 py-2 text-center text-fg ring-1 ring-line-strong ring-inset sm:text-sm placeholder:text-fg-subtle sm:leading-6 focus:ring-2 focus:ring-indigo-600 focus:ring-inset dark:bg-blue-gray-700"
75
75
  @input="onCodeInput($event, {{ i }})"
76
76
  @keydown="onKeyDown($event, {{ i }})"
77
77
  />
@@ -87,22 +87,22 @@ function onRecoveryCode(event) {
87
87
  </div>
88
88
  </form>
89
89
  <div>
90
- <p class="text-xs text-gray-700 dark:text-gray-300 font-semibold">
90
+ <p class="text-xs text-fg-strong font-semibold">
91
91
  {{ instructionText }}
92
92
  </p>
93
93
  </div>
94
94
  @if(showRecoveryCode)
95
95
  <div class="mt-4">
96
- <p class="text-xs text-gray-700 dark:text-gray-300 font-semibold">
96
+ <p class="text-xs text-fg-strong font-semibold">
97
97
  Having Problems?
98
98
  </p>
99
- <a
100
- href="#"
99
+ <button
100
+ type="button"
101
101
  @click="onRecoveryCode($event)"
102
102
  class="text-xs text-blue-500 hover:underline"
103
103
  >
104
104
  Use recovery code instead
105
- </a>
105
+ </button>
106
106
  </div>
107
107
  @endif
108
108
  </div>
@@ -20,7 +20,7 @@ export const aspectRatioClass = aspectRatio === '16/9' ? 'aspect-video' : aspect
20
20
  <div class="{{ containerClasses }}">
21
21
  @if(title)
22
22
  <div class="mb-2 px-1">
23
- <h3 class="text-sm font-medium text-gray-900 dark:text-gray-100">
23
+ <h3 class="text-sm font-medium text-fg">
24
24
  {{ title }}
25
25
  </h3>
26
26
  </div>
@@ -10,12 +10,12 @@ export const hoverable = $props.hoverable ?? true
10
10
  export const className = $props.className || ''
11
11
 
12
12
  export const totalHeight = data.length * rowHeight
13
- export const containerClasses = `border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden ${className}`.trim()
14
- export const headerClasses = `bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 flex`.trim()
15
- export const headerCellClasses = `px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider`.trim()
13
+ export const containerClasses = `border border-line rounded-lg overflow-hidden ${className}`.trim()
14
+ export const headerClasses = `bg-surface border-b border-line flex`.trim()
15
+ export const headerCellClasses = `px-6 py-3 text-left text-xs font-medium text-fg-soft uppercase tracking-wider`.trim()
16
16
  export const bodyClasses = `overflow-auto bg-white dark:bg-gray-900`.trim()
17
- export const rowClasses = `absolute left-0 right-0 flex border-b border-gray-200 dark:border-gray-700 ${hoverable ? 'hover:bg-gray-50 dark:hover:bg-gray-800' : ''}`.trim()
18
- export const cellClasses = `px-6 py-4 text-sm text-gray-900 dark:text-gray-100`.trim()
17
+ export const rowClasses = `absolute left-0 right-0 flex border-b border-line ${hoverable ? 'hover:bg-surface' : ''}`.trim()
18
+ export const cellClasses = `px-6 py-4 text-sm text-fg`.trim()
19
19
  </script>
20
20
 
21
21
  <script client>
@@ -86,7 +86,7 @@ defineExpose({ scrollTop })
86
86
  <div
87
87
  :for="entry in visibleRows()"
88
88
  :key="entry.index"
89
- :class="entry.striped ? '{{ rowClasses }} bg-gray-50 dark:bg-gray-800' : '{{ rowClasses }}'"
89
+ :class="entry.striped ? '{{ rowClasses }} bg-surface' : '{{ rowClasses }}'"
90
90
  :style="`top: ${entry.top}px; height: {{ rowHeight }}px`"
91
91
  :data-index="entry.index"
92
92
  >
package/dist/index.d.ts CHANGED
@@ -34,6 +34,8 @@ export { default as Hero } from './components/Hero.stx';
34
34
  export { default as Installation } from './components/Installation.stx';
35
35
  // Export composables
36
36
  export * from './composables/index';
37
+ // Theme seam — see src/theme for how an app redirects the components' colours.
38
+ export * from './theme/index';
37
39
  // Export UI components
38
40
  export * from './ui/accordion/index';
39
41
  export * from './ui/audio/index';