@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
@@ -11,10 +11,10 @@ export const allowMultiple = $props.allowMultiple || false
11
11
  export const defaultOpen = $props.defaultOpen || []
12
12
  export const className = $props.className || ''
13
13
 
14
- export const accordionClasses = `divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700 rounded-lg ${className}`.trim()
15
- export const headerClasses = `w-full flex items-center justify-between px-4 py-3 text-left font-medium text-gray-900 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900`.trim()
16
- export const iconClasses = `w-5 h-5 text-gray-500 dark:text-gray-400 transition-transform duration-200`.trim()
17
- export const contentClasses = `px-4 py-3 text-gray-700 dark:text-gray-300`.trim()
14
+ export const accordionClasses = `divide-y divide-line border border-line rounded-lg ${className}`.trim()
15
+ export const headerClasses = `w-full flex items-center justify-between px-4 py-3 text-left font-medium text-fg hover:bg-surface transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900`.trim()
16
+ export const iconClasses = `w-5 h-5 text-fg-soft transition-transform duration-200`.trim()
17
+ export const contentClasses = `px-4 py-3 text-fg-strong`.trim()
18
18
  export const hasPropItems = Array.isArray(items) && items.length > 0
19
19
  </script>
20
20
 
@@ -7,9 +7,9 @@
7
7
  export const title = $props.title || ''
8
8
  export const className = $props.className || ''
9
9
 
10
- const headerClasses = 'w-full flex items-center justify-between px-4 py-3 text-left font-medium text-gray-900 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900'
11
- const iconClasses = 'w-5 h-5 text-gray-500 dark:text-gray-400 transition-transform duration-200'
12
- const contentClasses = 'px-4 py-3 text-gray-700 dark:text-gray-300'
10
+ const headerClasses = 'w-full flex items-center justify-between px-4 py-3 text-left font-medium text-fg hover:bg-surface transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900'
11
+ const iconClasses = 'w-5 h-5 text-fg-soft transition-transform duration-200'
12
+ const contentClasses = 'px-4 py-3 text-fg-strong'
13
13
  </script>
14
14
 
15
15
  <div data-stx-accordion-item data-title="{{ title }}" class="{{ className }}">
@@ -10,13 +10,13 @@ export const showWaveform = $props.showWaveform || false
10
10
  export const title = $props.title || ''
11
11
 
12
12
  export const containerClasses = `relative w-full ${className}`.trim()
13
- export const audioClasses = 'w-full rounded-md bg-gray-100 dark:bg-gray-800'
13
+ export const audioClasses = 'w-full rounded-md bg-surface-raised'
14
14
  </script>
15
15
 
16
16
  <div class="{{ containerClasses }}">
17
17
  @if(title)
18
18
  <div class="mb-2 px-1">
19
- <h3 class="text-sm font-medium text-gray-900 dark:text-gray-100">
19
+ <h3 class="text-sm font-medium text-fg">
20
20
  {{ title }}
21
21
  </h3>
22
22
  </div>
@@ -35,7 +35,7 @@ export const audioClasses = 'w-full rounded-md bg-gray-100 dark:bg-gray-800'
35
35
  </audio>
36
36
 
37
37
  @if(showWaveform)
38
- <div class="mt-2 h-16 bg-gray-100 dark:bg-gray-800 rounded-md flex items-center justify-center">
38
+ <div class="mt-2 h-16 bg-surface-raised rounded-md flex items-center justify-center">
39
39
  <svg class="w-full h-full px-4" viewBox="0 0 100 40" preserveAspectRatio="none">
40
40
  <path
41
41
  d="M 0,20 L 10,15 L 20,10 L 30,5 L 40,15 L 50,20 L 60,25 L 70,30 L 80,20 L 90,15 L 100,20"
@@ -35,9 +35,9 @@ const statusColorClasses = {
35
35
  }
36
36
 
37
37
  export const containerClasses = `relative inline-block ${className}`.trim()
38
- export const avatarClasses = `flex items-center justify-center overflow-hidden bg-gray-200 dark:bg-gray-700 ${sizeClasses[size]} ${shapeClasses[shape]}`.trim()
38
+ export const avatarClasses = `flex items-center justify-center overflow-hidden bg-surface-sunken ${sizeClasses[size]} ${shapeClasses[shape]}`.trim()
39
39
  export const imageClasses = `w-full h-full object-cover`.trim()
40
- export const initialsClasses = `font-medium text-gray-600 dark:text-gray-300 uppercase select-none`.trim()
40
+ export const initialsClasses = `font-medium text-fg-muted uppercase select-none`.trim()
41
41
  export const statusClasses = status ? `absolute bottom-0 right-0 ${statusSizeClasses[size]} ${statusColorClasses[status]} ${shapeClasses[shape]} border-white dark:border-gray-900`.trim() : ''
42
42
  export const displayInitials = initials || (alt ? alt.split(' ').map(n => n[0]).join('').substring(0, 2) : '?')
43
43
  </script>
@@ -6,7 +6,7 @@ export const removable = $props.removable || false
6
6
  export const className = $props.className || ''
7
7
 
8
8
  const variantClasses = {
9
- default: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300',
9
+ default: 'bg-surface-raised text-gray-800 dark:text-gray-300',
10
10
  primary: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200',
11
11
  secondary: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200',
12
12
  success: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
@@ -19,10 +19,10 @@ const separatorElement = separator === '/' ? '/' :
19
19
  separator
20
20
 
21
21
  export const breadcrumbClasses = `flex items-center flex-wrap gap-2 text-sm ${className}`.trim()
22
- export const itemClasses = `text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 transition-colors duration-150`.trim()
23
- export const activeItemClasses = `text-gray-900 dark:text-gray-100 font-medium`.trim()
24
- export const separatorClasses = `text-gray-400 dark:text-gray-600 select-none`.trim()
25
- export const collapsedClasses = `text-gray-400 dark:text-gray-600 cursor-default`.trim()
22
+ export const itemClasses = `text-fg-muted hover:text-fg transition-colors duration-150`.trim()
23
+ export const activeItemClasses = `text-fg font-medium`.trim()
24
+ export const separatorClasses = `text-fg-subtle select-none`.trim()
25
+ export const collapsedClasses = `text-fg-subtle cursor-default`.trim()
26
26
  </script>
27
27
 
28
28
  <nav class="{{ breadcrumbClasses }}" aria-label="Breadcrumb">
@@ -47,8 +47,8 @@ export const collapsedClasses = `text-gray-400 dark:text-gray-600 cursor-default
47
47
  </span>
48
48
  @else
49
49
  <!-- Link item -->
50
- <a
51
- href="{{ item.href }}"
50
+ <StxLink
51
+ to="{{ item.href }}"
52
52
  class="{{ itemClasses }}"
53
53
  >
54
54
  @if(item.icon)
@@ -59,7 +59,7 @@ export const collapsedClasses = `text-gray-400 dark:text-gray-600 cursor-default
59
59
  @else
60
60
  {{ item.label }}
61
61
  @endif
62
- </a>
62
+ </StxLink>
63
63
  @endif
64
64
  @endif
65
65
 
@@ -11,9 +11,9 @@ export const className = $props.className || ''
11
11
 
12
12
  const variantClasses = {
13
13
  primary: 'bg-blue-500 hover:bg-blue-600 text-white shadow-md hover:shadow-lg dark:bg-blue-600 dark:hover:bg-blue-700',
14
- secondary: 'bg-neutral-200 hover:bg-neutral-300 text-neutral-900 dark:bg-neutral-700 dark:hover:bg-neutral-600 dark:text-white',
14
+ secondary: 'bg-surface-sunken hover:bg-neutral-300 text-neutral-900 dark:hover:bg-neutral-600 dark:text-white',
15
15
  outline: 'border-2 border-blue-500 text-blue-500 hover:bg-blue-50 dark:border-blue-400 dark:text-blue-400 dark:hover:bg-blue-950',
16
- ghost: 'hover:bg-neutral-100 text-neutral-700 dark:hover:bg-neutral-800 dark:text-neutral-300',
16
+ ghost: 'hover:bg-surface-raised text-fg-strong',
17
17
  danger: 'bg-red-500 hover:bg-red-600 text-white shadow-md hover:shadow-lg dark:bg-red-600 dark:hover:bg-red-700',
18
18
  }
19
19
 
@@ -12,10 +12,10 @@ export const highlightToday = $props.highlightToday !== false
12
12
  const baseClasses = 'bg-white dark:bg-gray-800 rounded-lg shadow-lg p-4 w-full max-w-sm'
13
13
  export const calendarClasses = `${baseClasses} ${className}`.trim()
14
14
  export const headerClasses = 'flex items-center justify-between mb-4'
15
- export const monthYearClasses = 'text-lg font-semibold text-gray-900 dark:text-gray-100'
16
- export const buttonClasses = 'p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md transition-colors'
15
+ export const monthYearClasses = 'text-lg font-semibold text-fg'
16
+ export const buttonClasses = 'p-2 hover:bg-surface-raised rounded-md transition-colors'
17
17
  export const weekdaysClasses = 'grid grid-cols-7 gap-1 mb-2'
18
- export const weekdayClasses = 'text-center text-xs font-medium text-gray-600 dark:text-gray-400 py-2'
18
+ export const weekdayClasses = 'text-center text-xs font-medium text-fg-muted py-2'
19
19
  export const daysGridClasses = 'grid grid-cols-7 gap-1'
20
20
 
21
21
  const valueIso = value ? new Date(value).toISOString() : null
@@ -121,10 +121,10 @@ function dayClasses(day) {
121
121
  const isTodayDate = isToday(day.date)
122
122
  const disabled = isDisabled(day.date)
123
123
  let cls = base
124
- cls += day.isCurrentMonth ? ' text-gray-900 dark:text-gray-100' : ' text-gray-400 dark:text-gray-600'
125
- cls += disabled ? ' opacity-50 cursor-not-allowed' : ' cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700'
126
- if (isSelected) cls += ' bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600'
127
- if (isTodayDate && highlightToday && !isSelected) cls += ' border-2 border-blue-600 dark:border-blue-400'
124
+ cls += day.isCurrentMonth ? 'text-fg' : 'text-fg-subtle'
125
+ cls += disabled ? ' opacity-50 cursor-not-allowed' : 'cursor-pointer hover:bg-surface-raised'
126
+ if (isSelected) cls += 'bg-info-solid text-white hover:bg-blue-700 dark:hover:bg-blue-600'
127
+ if (isTodayDate && highlightToday && !isSelected) cls += 'border-2 border-info'
128
128
  return cls
129
129
  }
130
130
 
@@ -179,7 +179,7 @@ defineExpose({ selectedDate, currentMonth, selectDate })
179
179
  <div class="mt-4 flex justify-center">
180
180
  <button
181
181
  type="button"
182
- class="px-4 py-2 text-sm font-medium text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-gray-700 rounded-md transition-colors"
182
+ class="px-4 py-2 text-sm font-medium text-info hover:bg-blue-50 dark:hover:bg-gray-700 rounded-md transition-colors"
183
183
  @click="goToToday()"
184
184
  >
185
185
  Today
@@ -8,10 +8,10 @@ export const imageAlt = $props.imageAlt || ''
8
8
  export const className = $props.className || ''
9
9
 
10
10
  const variantClasses = {
11
- default: 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700',
12
- outlined: 'bg-transparent border-2 border-gray-300 dark:border-gray-600',
11
+ default: 'bg-white dark:bg-gray-800 border border-line',
12
+ outlined: 'bg-transparent border-2 border-line-strong',
13
13
  elevated: 'bg-white dark:bg-gray-800 shadow-lg border-0',
14
- flat: 'bg-gray-50 dark:bg-gray-900 border-0',
14
+ flat: 'bg-surface border-0',
15
15
  }
16
16
 
17
17
  const paddingClasses = { none: 'p-0', sm: 'p-3', default: 'p-6', lg: 'p-8' }
@@ -12,13 +12,13 @@ export const name = $props.name || ''
12
12
  export const className = $props.className || ''
13
13
 
14
14
  const sizeClasses = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6' }
15
- const baseClasses = 'rounded 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'
16
- 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' : ''
15
+ const baseClasses = 'rounded border-line-strong text-accent focus:ring-accent focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 transition-colors'
16
+ const stateClasses = error ? 'border-red-300 dark:border-red-600 text-danger focus:ring-red-500 dark:focus:ring-red-400' : ''
17
17
  const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'
18
18
 
19
19
  export const checkboxClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses}`.trim()
20
- 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()
21
- export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
20
+ export const labelClasses = `text-sm font-medium ${error ? 'text-danger' : 'text-fg'} ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`.trim()
21
+ export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-fg-soft'}`.trim()
22
22
  export const inputId = `checkbox-${value || label}`
23
23
  </script>
24
24
 
@@ -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>
@@ -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-combobox-check>
35
+ <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-info" data-stx-combobox-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>
@@ -2,7 +2,7 @@
2
2
  export const className = $props.className || ''
3
3
  export const value = $props.value
4
4
 
5
- const baseClasses = 'flex cursor-pointer select-none items-center px-4 py-2 text-neutral-900 dark:text-neutral-100 hover:bg-blue-600 hover:text-white'
5
+ const baseClasses = 'flex cursor-pointer select-none items-center px-4 py-2 text-fg hover:bg-blue-600 hover:text-white'
6
6
  export const itemClasses = `${baseClasses} ${className}`.trim()
7
7
  </script>
8
8
 
@@ -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>
@@ -2,7 +2,7 @@
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'p'
4
4
 
5
- const baseClasses = 'mt-2 text-sm text-neutral-500 dark:text-neutral-400'
5
+ const baseClasses = 'mt-2 text-sm text-fg-soft'
6
6
  const descriptionClasses = `${baseClasses} ${className}`.trim()
7
7
  </script>
8
8
 
@@ -88,7 +88,7 @@ defineExpose({
88
88
  <div class="relative flex h-full flex-col overflow-y-auto bg-white dark:bg-blue-gray-800 py-6 shadow-xl">
89
89
  @if(title)
90
90
  <div class="px-4 sm:px-6">
91
- <h2 class="text-base font-semibold text-gray-900 dark:text-gray-100">
91
+ <h2 class="text-base font-semibold text-fg">
92
92
  {{ title }}
93
93
  </h2>
94
94
  </div>
@@ -4,7 +4,7 @@ export const as = $props.as || 'div'
4
4
  export const disabled = $props.disabled || false
5
5
  export const value = $props.value
6
6
 
7
- const baseClasses = 'group flex w-full items-center px-2 py-2 text-sm transition-colors text-neutral-900 dark:text-neutral-100 hover:bg-blue-500 hover:text-white dark:hover:bg-blue-600'
7
+ const baseClasses = 'group flex w-full items-center px-2 py-2 text-sm transition-colors text-fg hover:bg-blue-500 hover:text-white dark:hover:bg-blue-600'
8
8
  const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'
9
9
  export const itemClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
10
10
  </script>
@@ -10,7 +10,7 @@ export const validateOnChange = $props.validateOnChange === true
10
10
  export const validateOnBlur = $props.validateOnBlur === true
11
11
 
12
12
  export const formClasses = `space-y-6 ${className}`.trim()
13
- export const errorClasses = `mt-1 text-sm text-red-600 dark:text-red-400`.trim()
13
+ export const errorClasses = `mt-1 text-sm text-danger`.trim()
14
14
  </script>
15
15
 
16
16
  <script client>
@@ -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>
@@ -8,12 +8,28 @@ export const showSignup = $props.showSignup ?? true
8
8
  export const signupText = $props.signupText || 'Start a 14 day free trial'
9
9
  export const className = $props.className || ''
10
10
 
11
+ // These two used to be `href="#"`, which is not a link an app can wire — so
12
+ // adopting <Login> meant a form with two dead ends and no prop to fix them
13
+ // (#1930). They are real navigation, so they route through <StxLink>: an app on
14
+ // the SPA router gets a client-side transition, and an absolute URL still gets a
15
+ // native one because the router excludes those.
16
+ export const forgotPasswordHref = $props.forgotPasswordHref || '/forgot-password'
17
+ export const signupHref = $props.signupHref || '/register'
18
+
11
19
  export const containerClasses = `min-h-full flex flex-col justify-center py-12 lg:px-8 sm:px-6 dark:bg-blue-gray-900 ${className}`.trim()
12
20
  </script>
13
21
 
14
22
  <script client>
15
23
  const emit = defineEmits()
16
24
 
25
+ // The social buttons used to be `<a href="#">` — a link that navigates
26
+ // nowhere and that a host app had no way to wire (#1930). They are not
27
+ // navigation, so they are real buttons now, and the provider is emitted so
28
+ // the app can start its own OAuth flow.
29
+ function onSocial(provider) {
30
+ emit('social', { provider })
31
+ }
32
+
17
33
  function onSubmit(event) {
18
34
  event.preventDefault()
19
35
  const formData = new FormData(event.target)
@@ -32,7 +48,7 @@ function onSubmit(event) {
32
48
  @if(showLogo)
33
49
  <img src="/logo.svg" alt="Logo" class="mx-auto h-11 w-auto" />
34
50
  @endif
35
- <h2 class="mt-6 text-center text-2xl text-gray-900 dark:text-gray-100 font-bold leading-9 tracking-tight">
51
+ <h2 class="mt-6 text-center text-2xl text-fg font-bold leading-9 tracking-tight">
36
52
  {{ headingText }}
37
53
  </h2>
38
54
  </div>
@@ -42,7 +58,7 @@ function onSubmit(event) {
42
58
  <div class="bg-white dark:bg-blue-gray-800 px-6 py-12 shadow sm:rounded-lg sm:px-12">
43
59
  <div class="space-y-6">
44
60
  <div>
45
- <label for="email" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
61
+ <label for="email" class="block text-sm text-fg font-medium leading-6">
46
62
  Email address
47
63
  </label>
48
64
  <div class="mt-2">
@@ -52,13 +68,13 @@ function onSubmit(event) {
52
68
  type="email"
53
69
  autocomplete="email"
54
70
  required
55
- class="block w-full border-0 rounded-md py-1.5 text-gray-900 dark:text-gray-100 shadow-sm 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"
71
+ class="block w-full border-0 rounded-md py-1.5 text-fg shadow-sm 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"
56
72
  />
57
73
  </div>
58
74
  </div>
59
75
 
60
76
  <div>
61
- <label for="password" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
77
+ <label for="password" class="block text-sm text-fg font-medium leading-6">
62
78
  Password
63
79
  </label>
64
80
  <div class="mt-2">
@@ -68,7 +84,7 @@ function onSubmit(event) {
68
84
  type="password"
69
85
  autocomplete="current-password"
70
86
  required
71
- class="block w-full border-0 rounded-md py-1.5 text-gray-900 dark:text-gray-100 shadow-sm 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"
87
+ class="block w-full border-0 rounded-md py-1.5 text-fg shadow-sm 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"
72
88
  />
73
89
  </div>
74
90
  </div>
@@ -80,9 +96,9 @@ function onSubmit(event) {
80
96
  id="remember-me"
81
97
  name="remember-me"
82
98
  type="checkbox"
83
- class="h-4 w-4 border-gray-300 dark:border-gray-600 rounded text-indigo-600 focus:ring-indigo-600 dark:bg-blue-gray-700"
99
+ class="h-4 w-4 border-line-strong rounded text-indigo-600 focus:ring-indigo-600 dark:bg-blue-gray-700"
84
100
  />
85
- <label for="remember-me" class="ml-3 block text-sm text-gray-900 dark:text-gray-100 leading-6">
101
+ <label for="remember-me" class="ml-3 block text-sm text-fg leading-6">
86
102
  Remember me
87
103
  </label>
88
104
  </div>
@@ -90,9 +106,9 @@ function onSubmit(event) {
90
106
 
91
107
  @if(showForgotPassword)
92
108
  <div class="text-sm leading-6">
93
- <a href="#" class="text-indigo-600 dark:text-indigo-400 font-semibold hover:text-indigo-500 dark:hover:text-indigo-300">
109
+ <StxLink to="{{ forgotPasswordHref }}" class="text-accent font-semibold hover:text-indigo-500 dark:hover:text-indigo-300">
94
110
  Forgot password?
95
- </a>
111
+ </StxLink>
96
112
  </div>
97
113
  @endif
98
114
  </div>
@@ -111,19 +127,20 @@ function onSubmit(event) {
111
127
  <div>
112
128
  <div class="relative mt-10">
113
129
  <div class="absolute inset-0 flex items-center" aria-hidden="true">
114
- <div class="w-full border-t border-gray-200 dark:border-gray-600"></div>
130
+ <div class="w-full border-t border-line"></div>
115
131
  </div>
116
132
  <div class="relative flex justify-center text-sm font-medium leading-6">
117
- <span class="bg-white dark:bg-blue-gray-800 px-6 text-gray-900 dark:text-gray-100">
133
+ <span class="bg-white dark:bg-blue-gray-800 px-6 text-fg">
118
134
  Or continue with
119
135
  </span>
120
136
  </div>
121
137
  </div>
122
138
 
123
139
  <div class="grid grid-cols-2 mt-6 gap-4">
124
- <a
125
- href="#"
126
- class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-gray-100 font-semibold shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
140
+ <button
141
+ type="button"
142
+ @click="onSocial('google')"
143
+ class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-fg font-semibold shadow-sm ring-1 ring-line-strong ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
127
144
  >
128
145
  <svg class="h-5 w-5" viewBox="0 0 24 24" aria-hidden="true">
129
146
  <path d="M12.0003 4.75C13.7703 4.75 15.3553 5.36002 16.6053 6.54998L20.0303 3.125C17.9502 1.19 15.2353 0 12.0003 0C7.31028 0 3.25527 2.69 1.28027 6.60998L5.27028 9.70498C6.21525 6.86002 8.87028 4.75 12.0003 4.75Z" fill="#EA4335" />
@@ -132,28 +149,29 @@ function onSubmit(event) {
132
149
  <path d="M12.0004 24.0001C15.2404 24.0001 17.9654 22.935 19.9454 21.095L16.0804 18.095C15.0054 18.82 13.6204 19.245 12.0004 19.245C8.8704 19.245 6.21537 17.135 5.2654 14.29L1.27539 17.385C3.25539 21.31 7.3104 24.0001 12.0004 24.0001Z" fill="#34A853" />
133
150
  </svg>
134
151
  <span class="text-sm font-semibold leading-6">Google</span>
135
- </a>
152
+ </button>
136
153
 
137
- <a
138
- href="#"
139
- class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-gray-100 font-semibold shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
154
+ <button
155
+ type="button"
156
+ @click="onSocial('github')"
157
+ class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-fg font-semibold shadow-sm ring-1 ring-line-strong ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
140
158
  >
141
159
  <svg class="h-5 w-5 fill-[#24292F]" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
142
160
  <path fill-rule="evenodd" d="M10 0C4.477 0 0 4.484 0 10.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0110 4.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.203 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0020 10.017C20 4.484 15.522 0 10 0z" clip-rule="evenodd" />
143
161
  </svg>
144
162
  <span class="text-sm font-semibold leading-6">GitHub</span>
145
- </a>
163
+ </button>
146
164
  </div>
147
165
  </div>
148
166
  @endif
149
167
  </div>
150
168
 
151
169
  @if(showSignup)
152
- <p class="mt-10 text-center text-sm text-gray-500 dark:text-gray-400">
170
+ <p class="mt-10 text-center text-sm text-fg-soft">
153
171
  Not a member?
154
- <a href="#" class="text-indigo-600 dark:text-indigo-400 font-semibold leading-6 hover:text-indigo-500 dark:hover:text-indigo-300">
172
+ <StxLink to="{{ signupHref }}" class="text-accent font-semibold leading-6 hover:text-indigo-500 dark:hover:text-indigo-300">
155
173
  {{ signupText }}
156
- </a>
174
+ </StxLink>
157
175
  </p>
158
176
  @endif
159
177
  </div>
@@ -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