@threadlabs/looma 0.33.1 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/components/shared/overlay.js +8 -2
  2. package/components/shared/surface-material.js +21 -0
  3. package/components/ui-badge/ui-badge.html +11 -3
  4. package/components/ui-button/ui-button.html +92 -51
  5. package/components/ui-card/ui-card.html +50 -6
  6. package/components/ui-checkbox/ui-checkbox.html +4 -2
  7. package/components/ui-curve-editor/curve.js +10 -0
  8. package/components/ui-curve-editor/ui-curve-editor.html +181 -0
  9. package/components/ui-curve-editor/ui-curve-editor.js +51 -0
  10. package/components/ui-dialog/ui-dialog.html +64 -1
  11. package/components/ui-dialog/ui-dialog.js +9 -1
  12. package/components/ui-icon-button/ui-icon-button.html +97 -31
  13. package/components/ui-input/ui-input.html +2 -1
  14. package/components/ui-input-group/ui-input-group.html +4 -1
  15. package/components/ui-light-editor/ui-light-editor.html +45 -0
  16. package/components/ui-light-editor/ui-light-editor.js +53 -0
  17. package/components/ui-menu/ui-menu.html +62 -0
  18. package/components/ui-menu/ui-menu.js +1 -1
  19. package/components/ui-number-input/arithmetic.js +47 -0
  20. package/components/ui-number-input/ui-number-input.html +63 -0
  21. package/components/ui-number-input/ui-number-input.js +47 -0
  22. package/components/ui-popover/ui-popover.html +66 -1
  23. package/components/ui-popover/ui-popover.js +1 -1
  24. package/components/ui-select/ui-select.html +9 -7
  25. package/components/ui-slider/ui-slider.html +84 -0
  26. package/components/ui-slider/ui-slider.js +29 -0
  27. package/components/ui-switch/ui-switch.html +3 -0
  28. package/components/ui-tabs/ui-tabs.html +6 -1
  29. package/components/ui-text/ui-text.html +31 -6
  30. package/components/ui-textarea/ui-textarea.html +2 -1
  31. package/components/ui-tooltip/ui-tooltip.html +60 -0
  32. package/components/ui-tooltip/ui-tooltip.js +1 -1
  33. package/dist/index.js +47 -43
  34. package/docs/README.md +59 -5
  35. package/docs/card.html +16 -2
  36. package/docs/card.js +17 -2
  37. package/docs/catalog.json +1640 -108
  38. package/docs/customizer-render.mjs +50 -11
  39. package/docs/customizer.js +137 -24
  40. package/docs/documentation.css +9 -1
  41. package/docs/index.d.ts +8 -3
  42. package/docs/index.mjs +1 -1
  43. package/docs/preview.js +2 -0
  44. package/docs/render.mjs +16 -7
  45. package/docs/site.mjs +78 -27
  46. package/docs/theme-session.mjs +53 -0
  47. package/docs/theme.mjs +189 -18
  48. package/docs/value-editors.mjs +33 -0
  49. package/package.json +2 -2
  50. package/styles/ui-badge.css +11 -6
  51. package/styles/ui-button.css +74 -49
  52. package/styles/ui-card.css +51 -4
  53. package/styles/ui-checkbox.css +4 -2
  54. package/styles/ui-curve-editor.css +109 -0
  55. package/styles/ui-dialog.css +136 -0
  56. package/styles/ui-icon-button.css +85 -28
  57. package/styles/ui-input-group.css +4 -1
  58. package/styles/ui-input.css +2 -1
  59. package/styles/ui-light-editor.css +28 -0
  60. package/styles/ui-menu.css +74 -0
  61. package/styles/ui-number-input.css +34 -0
  62. package/styles/ui-popover.css +76 -0
  63. package/styles/ui-select.css +9 -7
  64. package/styles/ui-slider.css +53 -0
  65. package/styles/ui-switch.css +3 -0
  66. package/styles/ui-tabs.css +6 -1
  67. package/styles/ui-text.css +23 -1
  68. package/styles/ui-textarea.css +2 -1
  69. package/styles/ui-tooltip.css +72 -0
  70. package/theme-light.css +1 -0
  71. package/theme-system.css +69 -17
  72. package/tokens.css +12 -2
  73. package/vanilla/UiButton.d.ts +1 -0
  74. package/vanilla/UiButton.js +195 -130
  75. package/vanilla/UiCard.d.ts +1 -0
  76. package/vanilla/UiCard.js +12 -12
  77. package/vanilla/UiCurveEditor.d.ts +28 -0
  78. package/vanilla/UiCurveEditor.js +134 -0
  79. package/vanilla/UiIconButton.d.ts +2 -1
  80. package/vanilla/UiIconButton.js +58 -31
  81. package/vanilla/UiLightEditor.d.ts +29 -0
  82. package/vanilla/UiLightEditor.js +102 -0
  83. package/vanilla/UiNumberInput.d.ts +33 -0
  84. package/vanilla/UiNumberInput.js +86 -0
  85. package/vanilla/UiSlider.d.ts +33 -0
  86. package/vanilla/UiSlider.js +125 -0
  87. package/vanilla/UiText.d.ts +2 -2
  88. package/vanilla/UiText.js +45 -11
  89. package/vanilla/index.js +4 -0
  90. package/vue/UiBadge.vue +29 -4
  91. package/vue/UiButton.d.ts +6 -0
  92. package/vue/UiButton.vue +188 -60
  93. package/vue/UiCard.d.ts +6 -0
  94. package/vue/UiCard.vue +80 -6
  95. package/vue/UiCheckbox.vue +4 -2
  96. package/vue/UiCurveEditor.d.ts +53 -0
  97. package/vue/UiCurveEditor.js +2 -0
  98. package/vue/UiCurveEditor.vue +427 -0
  99. package/vue/UiDialog.vue +181 -1
  100. package/vue/UiIconButton.d.ts +8 -2
  101. package/vue/UiIconButton.vue +190 -45
  102. package/vue/UiInput.vue +2 -1
  103. package/vue/UiInputGroup.vue +4 -1
  104. package/vue/UiLightEditor.d.ts +75 -0
  105. package/vue/UiLightEditor.js +2 -0
  106. package/vue/UiLightEditor.vue +402 -0
  107. package/vue/UiMenu.vue +91 -0
  108. package/vue/UiNumberInput.d.ts +83 -0
  109. package/vue/UiNumberInput.js +2 -0
  110. package/vue/UiNumberInput.vue +399 -0
  111. package/vue/UiPopover.vue +94 -1
  112. package/vue/UiSelect.vue +16 -10
  113. package/vue/UiSlider.d.ts +83 -0
  114. package/vue/UiSlider.js +2 -0
  115. package/vue/UiSlider.vue +412 -0
  116. package/vue/UiSwitch.vue +3 -0
  117. package/vue/UiTabs.vue +6 -1
  118. package/vue/UiText.d.ts +7 -5
  119. package/vue/UiText.vue +104 -22
  120. package/vue/UiTextarea.vue +2 -1
  121. package/vue/UiTooltip.vue +89 -0
  122. package/vue/chunks/UiActionBar.js +1 -1
  123. package/vue/chunks/UiAffordanceScope.js +2 -2
  124. package/vue/chunks/UiAvatar.js +2 -2
  125. package/vue/chunks/UiAvatarGroup.js +2 -2
  126. package/vue/chunks/UiBadge.js +3 -3
  127. package/vue/chunks/UiBreadcrumbItem.js +2 -2
  128. package/vue/chunks/UiBreadcrumbs.js +2 -2
  129. package/vue/chunks/UiButton.js +94 -11
  130. package/vue/chunks/UiCallout.js +2 -2
  131. package/vue/chunks/UiCard.js +34 -5
  132. package/vue/chunks/UiCheckbox.js +3 -3
  133. package/vue/chunks/UiCluster.js +2 -2
  134. package/vue/chunks/UiColorPicker.js +2 -2
  135. package/vue/chunks/UiCombobox.js +2 -2
  136. package/vue/chunks/UiContainer.js +2 -2
  137. package/vue/chunks/UiContextMenu.js +2 -2
  138. package/vue/chunks/UiCover.js +2 -2
  139. package/vue/chunks/UiCurveEditor.js +413 -0
  140. package/vue/chunks/UiDescriptionItem.js +2 -2
  141. package/vue/chunks/UiDescriptionList.js +2 -2
  142. package/vue/chunks/UiDialog.js +4 -4
  143. package/vue/chunks/UiDisclosure.js +2 -2
  144. package/vue/chunks/UiEditable.js +2 -2
  145. package/vue/chunks/UiEditorBlockActions.js +2 -2
  146. package/vue/chunks/UiEditorChipEditor.js +2 -2
  147. package/vue/chunks/UiEditorCodeLanguage.js +2 -2
  148. package/vue/chunks/UiEditorFootnoteEditor.js +2 -2
  149. package/vue/chunks/UiEditorImageToolbar.js +3 -3
  150. package/vue/chunks/UiEditorInsertTableGrid.js +2 -2
  151. package/vue/chunks/UiEditorLinkCard.js +3 -3
  152. package/vue/chunks/UiEditorLinkForm.js +3 -3
  153. package/vue/chunks/UiEditorMentionMenu.js +2 -2
  154. package/vue/chunks/UiEditorMentionMenuItem.js +2 -2
  155. package/vue/chunks/UiEditorSlashMenu.js +2 -2
  156. package/vue/chunks/UiEditorSlashMenuGroup.js +2 -2
  157. package/vue/chunks/UiEditorSlashMenuItem.js +2 -2
  158. package/vue/chunks/UiEditorSurface.js +2 -2
  159. package/vue/chunks/UiEditorTableContextMenu.js +2 -2
  160. package/vue/chunks/UiEditorTableOverlay.js +2 -2
  161. package/vue/chunks/UiEditorTableToolbar.js +2 -2
  162. package/vue/chunks/UiEditorToolbar.js +2 -2
  163. package/vue/chunks/UiFloatingActionButton.js +2 -2
  164. package/vue/chunks/UiFormField.js +2 -2
  165. package/vue/chunks/UiGrid.js +2 -2
  166. package/vue/chunks/UiIcon.js +2 -2
  167. package/vue/chunks/UiIconButton.js +77 -11
  168. package/vue/chunks/UiImage.js +2 -2
  169. package/vue/chunks/UiInput.js +3 -3
  170. package/vue/chunks/UiInputGroup.js +3 -3
  171. package/vue/chunks/UiLightEditor.js +347 -0
  172. package/vue/chunks/UiList.js +2 -2
  173. package/vue/chunks/UiListItem.js +2 -2
  174. package/vue/chunks/UiListbox.js +2 -2
  175. package/vue/chunks/UiMenu.js +3 -3
  176. package/vue/chunks/UiMenuGroup.js +2 -2
  177. package/vue/chunks/UiMenuItem.js +2 -2
  178. package/vue/chunks/UiMeter.js +2 -2
  179. package/vue/chunks/UiNavItem.js +2 -2
  180. package/vue/chunks/UiNumberInput.js +403 -0
  181. package/vue/chunks/UiPageHeader.js +2 -2
  182. package/vue/chunks/UiPopover.js +4 -4
  183. package/vue/chunks/UiRadio.js +2 -2
  184. package/vue/chunks/UiRadioGroup.js +2 -2
  185. package/vue/chunks/UiReel.js +2 -2
  186. package/vue/chunks/UiScrollArea.js +2 -2
  187. package/vue/chunks/UiSearchResultRow.js +2 -2
  188. package/vue/chunks/UiSearchShell.js +2 -2
  189. package/vue/chunks/UiSection.js +2 -2
  190. package/vue/chunks/UiSelect.js +3 -3
  191. package/vue/chunks/UiSeparator.js +2 -2
  192. package/vue/chunks/UiSidebar.js +2 -2
  193. package/vue/chunks/UiSlider.js +396 -0
  194. package/vue/chunks/UiSpinner.js +2 -2
  195. package/vue/chunks/UiStack.js +2 -2
  196. package/vue/chunks/UiStatusMessage.js +2 -2
  197. package/vue/chunks/UiSwatch.js +2 -2
  198. package/vue/chunks/UiSwitch.js +3 -3
  199. package/vue/chunks/UiSwitcher.js +2 -2
  200. package/vue/chunks/UiTable.js +2 -2
  201. package/vue/chunks/UiTabs.js +3 -3
  202. package/vue/chunks/UiText.js +53 -12
  203. package/vue/chunks/UiTextarea.js +3 -3
  204. package/vue/chunks/UiToast.js +2 -2
  205. package/vue/chunks/UiToastRegion.js +2 -2
  206. package/vue/chunks/UiTooltip.js +3 -3
  207. package/vue/chunks/UiTopBar.js +1 -1
  208. package/vue/chunks/UiTree.js +2 -2
  209. package/vue/chunks/UiTreeItem.js +2 -2
  210. package/vue/chunks/_plugin-vue_export-helper.js +68 -2
  211. package/vue/chunks/props.js +24 -1
  212. package/vue/components.css +3391 -2139
  213. package/vue/editor/index.js +623 -211
  214. package/vue/index.d.ts +4 -0
  215. package/vue/index.js +6 -2
package/vue/UiButton.vue CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  checkHydratedRoot,
8
8
  concat,
9
9
  createDispatch,
10
+ cycleCheckedComputed,
10
11
  nativeAttrs,
11
12
  preserveRootFocus,
12
13
  useComponentHost,
@@ -17,6 +18,9 @@ import {
17
18
  checkedProp,
18
19
  checkPropInput,
19
20
  type InputBindings,
21
+ inputComputed,
22
+ inputDefault,
23
+ inputRead,
20
24
  propValidityState,
21
25
  READY_INPUT,
22
26
  requireInputStatus,
@@ -79,6 +83,15 @@ const propValidityContract = {
79
83
  description: 'Deprecated alias for loading.',
80
84
  default: false,
81
85
  },
86
+ preset: {
87
+ type: { kind: 'terminal', name: 'keyword' },
88
+ required: false,
89
+ target: { attribute: 'preset' },
90
+ description:
91
+ 'A shortcut that sets appearance and tone together: primary is solid accent, standard is solid neutral, quiet is ghost neutral, and destructive is solid\n danger. A named preset takes precedence over variant and tone. Leave it at none to choose variant and tone independently.',
92
+ values: ['none', 'primary', 'standard', 'quiet', 'destructive'],
93
+ default: 'none',
94
+ },
82
95
  rel: {
83
96
  type: { kind: 'terminal', name: 'string' },
84
97
  required: false,
@@ -153,6 +166,11 @@ const props = defineProps({
153
166
  href: { type: null as unknown as PropType<string | null> },
154
167
  loading: { type: null as unknown as PropType<boolean | null> },
155
168
  pending: { type: null as unknown as PropType<boolean | null> },
169
+ preset: {
170
+ type: null as unknown as PropType<
171
+ 'none' | 'primary' | 'standard' | 'quiet' | 'destructive' | null
172
+ >,
173
+ },
156
174
  rel: { type: null as unknown as PropType<string | null> },
157
175
  shape: { type: null as unknown as PropType<'rounded' | 'pill' | null> },
158
176
  size: { type: null as unknown as PropType<'xs' | 'sm' | 'md' | 'lg' | null> },
@@ -178,6 +196,7 @@ const acceptedProps: Record<string, unknown> = {
178
196
  href: null,
179
197
  loading: false,
180
198
  pending: false,
199
+ preset: 'none',
181
200
  rel: null,
182
201
  shape: 'rounded',
183
202
  size: 'md',
@@ -193,6 +212,7 @@ const inputTracking = vuePropInputs(acceptedProps, {
193
212
  disabled: false,
194
213
  loading: false,
195
214
  pending: false,
215
+ preset: 'none',
196
216
  shape: 'rounded',
197
217
  size: 'md',
198
218
  stretch: false,
@@ -213,6 +233,8 @@ const inputTracking = vuePropInputs(acceptedProps, {
213
233
  return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
214
234
  case 'pending':
215
235
  return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
236
+ case 'preset':
237
+ return checkPropInput(value, { kind: 'terminal', name: 'keyword' }, true, true)
216
238
  case 'rel':
217
239
  return checkPropInput(value, { kind: 'terminal', name: 'string' }, true, true)
218
240
  case 'shape':
@@ -263,6 +285,11 @@ const checkedProps = computed(() => {
263
285
  props['pending'],
264
286
  props[BINDING_INPUTS_PROP],
265
287
  ) as boolean,
288
+ preset: propInputs.value<'none' | 'primary' | 'standard' | 'quiet' | 'destructive' | null>(
289
+ 'preset',
290
+ props['preset'],
291
+ props[BINDING_INPUTS_PROP],
292
+ ) as 'none' | 'primary' | 'standard' | 'quiet' | 'destructive',
266
293
  rel: propInputs.value<string | null>('rel', props['rel'], props[BINDING_INPUTS_PROP]),
267
294
  shape: propInputs.value<'rounded' | 'pill' | null>(
268
295
  'shape',
@@ -317,6 +344,68 @@ const hydrationInstance = getCurrentInstance()
317
344
  const rootArmElement = useTemplateRef<HTMLElement>('@html-next/root')
318
345
  const root = rootArmElement
319
346
  preserveRootFocus(root)
347
+ const appearance: ReturnType<typeof inputComputed<any>> = inputComputed<any>(
348
+ () =>
349
+ (({
350
+ none: inputRead(checkedProps.value.variant, propInputs.status('variant')),
351
+ primary: 'solid',
352
+ standard: 'solid',
353
+ quiet: 'ghost',
354
+ destructive: 'solid',
355
+ }) as Record<string, any>)[
356
+ inputRead(checkedProps.value.preset, propInputs.status('preset'))
357
+ ] as any,
358
+ (read) => {
359
+ const value = cycleCheckedComputed(read)
360
+ return { get: () => value.value }
361
+ },
362
+ )
363
+ let colorTonePrevious: any = null
364
+ const colorTone: ReturnType<typeof inputComputed<any>> = inputComputed<any>(
365
+ () => {
366
+ return ((objectValue: any, indexValue: any) =>
367
+ objectValue === Symbol.for('html-next.invalid-result')
368
+ || indexValue === Symbol.for('html-next.invalid-result')
369
+ ? Symbol.for('html-next.invalid-result')
370
+ : objectValue[indexValue])(
371
+ (() => {
372
+ const value = {
373
+ none: ((objectValue: any, indexValue: any) =>
374
+ objectValue === Symbol.for('html-next.invalid-result')
375
+ || indexValue === Symbol.for('html-next.invalid-result')
376
+ ? Symbol.for('html-next.invalid-result')
377
+ : objectValue[indexValue])(
378
+ {
379
+ true: 'danger',
380
+ false: inputRead(checkedProps.value.tone, propInputs.status('tone')),
381
+ },
382
+ concat(
383
+ inputRead(checkedProps.value.variant, propInputs.status('variant')) === 'danger',
384
+ ),
385
+ ),
386
+ primary: 'accent',
387
+ standard: 'neutral',
388
+ quiet: 'neutral',
389
+ destructive: 'danger',
390
+ }
391
+ return Object.values(value).some((entry: unknown) =>
392
+ entry === Symbol.for('html-next.invalid-result')
393
+ )
394
+ ? Symbol.for('html-next.invalid-result')
395
+ : value
396
+ })(),
397
+ inputRead(checkedProps.value.preset, propInputs.status('preset')),
398
+ ) as any
399
+ },
400
+ (read) => {
401
+ const value = cycleCheckedComputed(read)
402
+ return { get: () => value.value }
403
+ },
404
+ next =>
405
+ (next as unknown) === Symbol.for('html-next.invalid-result')
406
+ ? colorTonePrevious
407
+ : (colorTonePrevious = next),
408
+ )
320
409
  let guardedPrevious: any = null
321
410
  const guarded = computed(() => {
322
411
  const candidate: any = ((objectValue: any, indexValue: any) =>
@@ -596,9 +685,9 @@ const guardedBinding7 = computed(() => {
596
685
  ))
597
686
  })
598
687
  checkHydratedRoot(
599
- (checkedProps.value.variant === 'card' && checkedProps.value.as === 'a')
688
+ (appearance.get() === 'card' && checkedProps.value.as === 'a')
600
689
  ? 'a'
601
- : ((checkedProps.value.variant === 'card')
690
+ : ((appearance.get() === 'card')
602
691
  ? 'button'
603
692
  : ((checkedProps.value.as === 'a') ? 'a' : ('button'))),
604
693
  'ui-button',
@@ -614,11 +703,6 @@ const hostState = computed(() =>
614
703
  checkedProps.value.size != null && `size=${encodeURIComponent(checkedProps.value.size)}`,
615
704
  checkedProps.value.shape && 'shape',
616
705
  checkedProps.value.shape != null && `shape=${encodeURIComponent(checkedProps.value.shape)}`,
617
- checkedProps.value.variant && 'variant',
618
- checkedProps.value.variant != null
619
- && `variant=${encodeURIComponent(checkedProps.value.variant)}`,
620
- checkedProps.value.tone && 'tone',
621
- checkedProps.value.tone != null && `tone=${encodeURIComponent(checkedProps.value.tone)}`,
622
706
  checkedProps.value.loading && 'loading',
623
707
  checkedProps.value.pending && 'pending',
624
708
  ].filter(Boolean).join(' ')
@@ -651,6 +735,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
651
735
  'href',
652
736
  'loading',
653
737
  'pending',
738
+ 'preset',
654
739
  'rel',
655
740
  'shape',
656
741
  'size',
@@ -662,16 +747,20 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
662
747
  ],
663
748
  propValidity: (name: string) =>
664
749
  propValidityState({ contract: propValidityContract, values: { ...props } }, name),
750
+ computed: { appearance, colorTone },
751
+ availability: { appearance: () => appearance.status(), colorTone: () => colorTone.status() },
665
752
  })
666
753
  </script>
667
754
 
668
755
  <template>
669
756
  <a
670
- v-if="checkedProps.variant === 'card' && checkedProps.as === 'a'"
757
+ v-if="appearance.get() === 'card' && checkedProps.as === 'a'"
671
758
  class="ui-button"
672
759
  v-bind="nativeAttrs($attrs)"
673
760
  data-hn
674
761
  data-hn-ui-button
762
+ :data-appearance="attribute(appearance.get())"
763
+ :data-tone="attribute(colorTone.get())"
675
764
  :href="guarded"
676
765
  :target="checkedProps.target ?? undefined"
677
766
  :rel="checkedProps.rel ?? undefined"
@@ -685,6 +774,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
685
774
  :data-ui-button-prop-href="reflectedProp('href', 'href', checkedProps.href, undefined, false)"
686
775
  :data-ui-button-prop-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
687
776
  :data-ui-button-prop-pending="reflectedProp('pending', 'pending', checkedProps.pending, undefined, false)"
777
+ :data-ui-button-prop-preset="reflectedProp('preset', 'preset', checkedProps.preset, undefined, false)"
688
778
  :data-ui-button-prop-rel="reflectedProp('rel', 'rel', checkedProps.rel, undefined, false)"
689
779
  :data-ui-button-prop-shape="reflectedProp('shape', 'shape', checkedProps.shape, undefined, false)"
690
780
  :data-ui-button-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
@@ -710,11 +800,13 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
710
800
  aria-hidden="true"
711
801
  /></slot></span></a>
712
802
  <button
713
- v-else-if="checkedProps.variant === 'card'"
803
+ v-else-if="appearance.get() === 'card'"
714
804
  class="ui-button"
715
805
  v-bind="nativeAttrs($attrs)"
716
806
  data-hn
717
807
  data-hn-ui-button
808
+ :data-appearance="attribute(appearance.get())"
809
+ :data-tone="attribute(colorTone.get())"
718
810
  :type="checkedProps.type ?? undefined"
719
811
  :disabled="checkedProps.disabled ?? undefined"
720
812
  :aria-disabled="guardedBinding3"
@@ -726,6 +818,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
726
818
  :data-ui-button-prop-href="reflectedProp('href', 'href', checkedProps.href, undefined, false)"
727
819
  :data-ui-button-prop-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
728
820
  :data-ui-button-prop-pending="reflectedProp('pending', 'pending', checkedProps.pending, undefined, false)"
821
+ :data-ui-button-prop-preset="reflectedProp('preset', 'preset', checkedProps.preset, undefined, false)"
729
822
  :data-ui-button-prop-rel="reflectedProp('rel', 'rel', checkedProps.rel, undefined, false)"
730
823
  :data-ui-button-prop-shape="reflectedProp('shape', 'shape', checkedProps.shape, undefined, false)"
731
824
  :data-ui-button-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
@@ -758,6 +851,8 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
758
851
  v-bind="nativeAttrs($attrs)"
759
852
  data-hn
760
853
  data-hn-ui-button
854
+ :data-appearance="attribute(appearance.get())"
855
+ :data-tone="attribute(colorTone.get())"
761
856
  :href="guardedBinding4"
762
857
  :target="checkedProps.target ?? undefined"
763
858
  :rel="checkedProps.rel ?? undefined"
@@ -771,6 +866,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
771
866
  :data-ui-button-prop-href="reflectedProp('href', 'href', checkedProps.href, undefined, false)"
772
867
  :data-ui-button-prop-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
773
868
  :data-ui-button-prop-pending="reflectedProp('pending', 'pending', checkedProps.pending, undefined, false)"
869
+ :data-ui-button-prop-preset="reflectedProp('preset', 'preset', checkedProps.preset, undefined, false)"
774
870
  :data-ui-button-prop-rel="reflectedProp('rel', 'rel', checkedProps.rel, undefined, false)"
775
871
  :data-ui-button-prop-shape="reflectedProp('shape', 'shape', checkedProps.shape, undefined, false)"
776
872
  :data-ui-button-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
@@ -795,6 +891,8 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
795
891
  v-bind="nativeAttrs($attrs)"
796
892
  data-hn
797
893
  data-hn-ui-button
894
+ :data-appearance="attribute(appearance.get())"
895
+ :data-tone="attribute(colorTone.get())"
798
896
  :type="checkedProps.type ?? undefined"
799
897
  :disabled="checkedProps.disabled ?? undefined"
800
898
  :aria-disabled="guardedBinding7"
@@ -806,6 +904,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
806
904
  :data-ui-button-prop-href="reflectedProp('href', 'href', checkedProps.href, undefined, false)"
807
905
  :data-ui-button-prop-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
808
906
  :data-ui-button-prop-pending="reflectedProp('pending', 'pending', checkedProps.pending, undefined, false)"
907
+ :data-ui-button-prop-preset="reflectedProp('preset', 'preset', checkedProps.preset, undefined, false)"
809
908
  :data-ui-button-prop-rel="reflectedProp('rel', 'rel', checkedProps.rel, undefined, false)"
810
909
  :data-ui-button-prop-shape="reflectedProp('shape', 'shape', checkedProps.shape, undefined, false)"
811
910
  :data-ui-button-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
@@ -952,7 +1051,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
952
1051
  :global(:scope:where([data-hn-ui-button])) {
953
1052
  /* Optional inherited action-group values keep text and icon actions under the same light.
954
1053
  One fine top/start highlight follows the bottom/end lowlight at a joined action seam.
955
- A single ambient lift avoids stacking a face gradient or another inset bevel. */
1054
+ The shared theme supplies reflections and glow independently of the resting lift. */
956
1055
  --_ui-action-start: 1px;
957
1056
  --_ui-action-edge: var(
958
1057
  --ui-action-edge,
@@ -968,6 +1067,8 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
968
1067
  --_ui-action-shadow:
969
1068
  var(--_ui-action-edge),
970
1069
  0 1px 2px light-dark(rgb(0 0 0 / 0.10), rgb(0 0 0 / 0.20));
1070
+ --_tone-highlight: var(--ui-accent-highlight, none);
1071
+ --_tone-glow: var(--ui-accent-glow, 0 0 transparent);
971
1072
  --_hue: var(--ui-accent);
972
1073
  --_hue-hover: var(--ui-accent-hover);
973
1074
  --_hue-active: var(--ui-accent-active);
@@ -1019,8 +1120,10 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1019
1120
  line-height: var(--ui-line-height-tight);
1020
1121
  padding: var(--ui-control-inset-block-md, var(--ui-space-2))
1021
1122
  var(--ui-action-inset-md, var(--ui-space-3)) !important;
1022
- background-image: none;
1023
- box-shadow: var(--ui-button-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
1123
+ background-image: var(--ui-surface-highlight, none);
1124
+ box-shadow:
1125
+ var(--ui-button-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
1126
+ var(--_tone-glow);
1024
1127
  cursor: pointer;
1025
1128
  transition:
1026
1129
  scale var(--ui-motion-press, var(--ui-motion-fast)) var(--ui-motion-ease),
@@ -1039,7 +1142,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1039
1142
  flex: none;
1040
1143
  vertical-align: middle;
1041
1144
  }
1042
- :global(:scope:not([variant="link"]):has(.badge:not(:empty)):where([data-hn-ui-button])) {
1145
+ :global(:scope:not([data-appearance="link"]):has(.badge:not(:empty)):where([data-hn-ui-button])) {
1043
1146
  padding-block: var(--ui-space-0-5) !important;
1044
1147
  }
1045
1148
 
@@ -1083,7 +1186,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1083
1186
  var(--ui-action-inset-lg, var(--ui-space-4)) !important;
1084
1187
  font-size: var(--ui-font-size-md);
1085
1188
  }
1086
- :global(:scope[data-ui-button-state~="variant=card"]:where([data-hn-ui-button])) {
1189
+ :global(:scope[data-appearance="card"]:where([data-hn-ui-button])) {
1087
1190
  display: grid !important;
1088
1191
  grid-template-columns: auto minmax(0, 1fr) auto;
1089
1192
  align-content: center !important;
@@ -1096,10 +1199,10 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1096
1199
  box-shadow: none;
1097
1200
  background-image: none;
1098
1201
  }
1099
- :global(:scope[data-ui-button-state~="variant=card"][data-ui-button-state~="size=lg"]:where([data-hn-ui-button])) {
1202
+ :global(:scope[data-appearance="card"][size="lg"]:where([data-hn-ui-button])) {
1100
1203
  min-block-size: max(var(--ui-control-min-block-size), var(--ui-control-size-lg));
1101
1204
  }
1102
- :global(:scope[data-ui-button-state~="variant=card"]:has(.card-icon:empty):where([data-hn-ui-button])) {
1205
+ :global(:scope[data-appearance="card"]:has(.card-icon:empty):where([data-hn-ui-button])) {
1103
1206
  grid-template-columns: minmax(0, 1fr) auto;
1104
1207
  }
1105
1208
  :global(.card-icon:where([data-hn-ui-button])) {
@@ -1121,11 +1224,11 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1121
1224
  border-color: var(--ui-button-hover-border, var(--_tone-hover));
1122
1225
  background-color: var(--ui-button-hover-surface, oklch(from var(--_tone) l c h / 12%));
1123
1226
  }
1124
- :global(:scope[data-ui-button-state~="variant=card"][data-ui-button-state~="tone=neutral"]:where([data-hn-ui-button])) {
1227
+ :global(:scope[data-appearance="card"][data-tone="neutral"]:where([data-hn-ui-button])) {
1125
1228
  border-color: var(--ui-button-border, var(--ui-border));
1126
1229
  }
1127
1230
 
1128
- :global(:scope[data-ui-button-state~="variant=card"][data-ui-button-state~="tone=neutral"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1231
+ :global(:scope[data-appearance="card"][data-tone="neutral"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1129
1232
  border-color: var(--ui-button-hover-border, var(--ui-border-strong));
1130
1233
  }
1131
1234
  :global(:scope:active:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
@@ -1135,26 +1238,31 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1135
1238
  box-shadow: var(--ui-pressed);
1136
1239
  }
1137
1240
 
1138
- :global(:scope[data-ui-button-state~="variant=solid"]:where([data-hn-ui-button])),
1139
- :global(:scope[data-ui-button-state~="variant=danger"]:where([data-hn-ui-button])) {
1241
+ :global(:scope[data-appearance="solid"]:where([data-hn-ui-button])),
1242
+ :global(:scope[data-appearance="danger"]:where([data-hn-ui-button])) {
1140
1243
  border-color: var(--_tone);
1141
1244
  background-color: var(--_tone);
1142
1245
  color: var(--_on-tone);
1143
- box-shadow: var(--ui-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
1246
+ background-image: var(--_tone-highlight);
1247
+ box-shadow:
1248
+ var(--ui-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
1249
+ var(--_tone-glow);
1144
1250
  }
1145
1251
 
1146
- :global(:is(:scope[data-ui-button-state~="variant=solid"], :scope[data-ui-button-state~="variant=danger"]):hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1252
+ :global(:is(:scope[data-appearance="solid"], :scope[data-appearance="danger"]):hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1147
1253
  background-color: var(--_tone-hover);
1148
1254
  border-color: var(--_tone-hover);
1149
1255
  }
1150
1256
 
1151
- :global(:is(:scope[data-ui-button-state~="variant=solid"], :scope[data-ui-button-state~="variant=danger"]):active:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1257
+ :global(:is(:scope[data-appearance="solid"], :scope[data-appearance="danger"]):active:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1152
1258
  background-color: var(--_tone-active);
1153
1259
  border-color: var(--_tone-active);
1154
1260
  background-image: none;
1155
1261
  box-shadow: var(--ui-pressed);
1156
1262
  }
1157
- :global(:scope[data-ui-button-state~="tone=neutral"]:where([data-hn-ui-button])) {
1263
+ :global(:scope[data-tone="neutral"]:where([data-hn-ui-button])) {
1264
+ --_tone-highlight: var(--ui-neutral-highlight, none);
1265
+ --_tone-glow: var(--ui-neutral-glow, 0 0 transparent);
1158
1266
  --_hue: var(--ui-text);
1159
1267
  --_hue-hover: var(--ui-text);
1160
1268
  --_hue-active: var(--ui-text);
@@ -1162,39 +1270,59 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1162
1270
  --_on-hue: var(--ui-surface);
1163
1271
  }
1164
1272
 
1165
- :global(:scope[data-ui-button-state~="tone=danger"]:where([data-hn-ui-button])),
1166
- :global(:scope[data-ui-button-state~="variant=danger"]:where([data-hn-ui-button])) {
1273
+ :global(:scope[data-tone="neutral"][data-appearance="solid"]:where([data-hn-ui-button])) {
1274
+ border-color: var(--ui-button-border, var(--ui-control-border));
1275
+ background-color: var(--ui-button-surface, var(--ui-neutral-surface));
1276
+ color: var(--ui-button-text, var(--ui-text));
1277
+ }
1278
+ :global(:scope[data-tone="neutral"][data-appearance="solid"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1279
+ background-color: var(--ui-button-hover-surface, var(--ui-neutral-hover));
1280
+ }
1281
+ :global(:scope[data-tone="neutral"][data-appearance="solid"]:active:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1282
+ background-color: var(--ui-button-active-surface, var(--ui-neutral-active));
1283
+ }
1284
+
1285
+ :global(:scope[data-tone="danger"]:where([data-hn-ui-button])),
1286
+ :global(:scope[data-appearance="danger"]:where([data-hn-ui-button])) {
1287
+ --_tone-highlight: var(--ui-danger-highlight, none);
1288
+ --_tone-glow: var(--ui-danger-glow, 0 0 transparent);
1167
1289
  --_hue: var(--ui-danger);
1168
1290
  --_hue-hover: var(--ui-danger-hover);
1169
- --_hue-active: var(--ui-danger-hover);
1170
- --_hue-text: var(--ui-danger-hover);
1291
+ --_hue-active: var(--ui-danger-active, var(--ui-danger-hover));
1292
+ --_hue-text: var(--ui-danger-subtle-text);
1171
1293
  --_on-hue: var(--ui-on-danger);
1172
1294
  }
1173
1295
 
1174
- :global(:scope[data-ui-button-state~="tone=success"]:where([data-hn-ui-button])) {
1296
+ :global(:scope[data-tone="success"]:where([data-hn-ui-button])) {
1297
+ --_tone-highlight: var(--ui-success-highlight, none);
1298
+ --_tone-glow: var(--ui-success-glow, 0 0 transparent);
1175
1299
  --_hue: var(--ui-success);
1176
- --_hue-hover: color-mix(in srgb, var(--ui-success) 85%, #000);
1177
- --_hue-active: color-mix(in srgb, var(--ui-success) 75%, #000);
1178
- --_hue-text: color-mix(in srgb, var(--ui-success) 85%, #000);
1179
- --_on-hue: var(--ui-surface);
1300
+ --_hue-hover: var(--ui-success-hover);
1301
+ --_hue-active: var(--ui-success-active);
1302
+ --_hue-text: var(--ui-success-subtle-text);
1303
+ --_on-hue: var(--ui-success-on-strong);
1180
1304
  }
1181
1305
 
1182
- :global(:scope[data-ui-button-state~="tone=warning"]:where([data-hn-ui-button])) {
1306
+ :global(:scope[data-tone="warning"]:where([data-hn-ui-button])) {
1307
+ --_tone-highlight: var(--ui-warning-highlight, none);
1308
+ --_tone-glow: var(--ui-warning-glow, 0 0 transparent);
1183
1309
  --_hue: var(--ui-warning);
1184
- --_hue-hover: color-mix(in srgb, var(--ui-warning) 85%, #000);
1185
- --_hue-active: color-mix(in srgb, var(--ui-warning) 75%, #000);
1186
- --_hue-text: color-mix(in srgb, var(--ui-warning) 85%, #000);
1187
- --_on-hue: var(--ui-surface);
1310
+ --_hue-hover: var(--ui-warning-hover);
1311
+ --_hue-active: var(--ui-warning-active);
1312
+ --_hue-text: var(--ui-warning-subtle-text);
1313
+ --_on-hue: var(--ui-warning-on-strong);
1188
1314
  }
1189
1315
 
1190
- :global(:scope[data-ui-button-state~="tone=info"]:where([data-hn-ui-button])) {
1316
+ :global(:scope[data-tone="info"]:where([data-hn-ui-button])) {
1317
+ --_tone-highlight: var(--ui-info-highlight, none);
1318
+ --_tone-glow: var(--ui-info-glow, 0 0 transparent);
1191
1319
  --_hue: var(--ui-info);
1192
- --_hue-hover: color-mix(in srgb, var(--ui-info) 85%, #000);
1193
- --_hue-active: color-mix(in srgb, var(--ui-info) 75%, #000);
1194
- --_hue-text: color-mix(in srgb, var(--ui-info) 85%, #000);
1195
- --_on-hue: var(--ui-surface);
1320
+ --_hue-hover: var(--ui-info-hover);
1321
+ --_hue-active: var(--ui-info-active);
1322
+ --_hue-text: var(--ui-info-subtle-text);
1323
+ --_on-hue: var(--ui-info-on-strong);
1196
1324
  }
1197
- :global(:scope[data-ui-button-state~="variant=field"]:where([data-hn-ui-button])) {
1325
+ :global(:scope[data-appearance="field"]:where([data-hn-ui-button])) {
1198
1326
  --_ui-field-shadow: var(--ui-shadow-sm);
1199
1327
  border-color: var(--ui-button-border, var(--ui-control-border, var(--ui-border-strong)));
1200
1328
  border-radius: var(--ui-button-radius, var(--ui-field-radius, var(--ui-radius-md)));
@@ -1207,7 +1335,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1207
1335
  box-shadow: var(--ui-button-shadow, var(--_ui-field-shadow));
1208
1336
  }
1209
1337
 
1210
- :global(:scope[data-ui-button-state~="variant=field"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1338
+ :global(:scope[data-appearance="field"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1211
1339
  border-color: var(
1212
1340
  --ui-button-hover-border,
1213
1341
  var(--ui-control-border-hover, var(--ui-text-secondary))
@@ -1218,28 +1346,28 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1218
1346
  );
1219
1347
  }
1220
1348
 
1221
- :global(:scope[data-ui-button-state~="variant=field"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1349
+ :global(:scope[data-appearance="field"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1222
1350
  --_ui-field-shadow: var(--ui-pressed);
1223
1351
  }
1224
1352
 
1225
- :global(:scope[data-ui-button-state~="variant=field"]:focus-visible:where([data-hn-ui-button])) {
1353
+ :global(:scope[data-appearance="field"]:focus-visible:where([data-hn-ui-button])) {
1226
1354
  border-color: var(--ui-control-focus, var(--ui-accent-solid));
1227
1355
  box-shadow:
1228
1356
  var(--ui-button-shadow, var(--_ui-field-shadow)),
1229
1357
  var(--ui-control-focus-halo-shadow);
1230
1358
  }
1231
1359
 
1232
- :global(:scope[data-ui-button-state~="variant=ghost"]:where([data-hn-ui-button])) {
1360
+ :global(:scope[data-appearance="ghost"]:where([data-hn-ui-button])) {
1233
1361
  border-color: transparent;
1234
1362
  background: transparent;
1235
1363
  box-shadow: none;
1236
1364
  color: var(--ui-button-ghost-text, var(--_tone-text));
1237
1365
  }
1238
- :global(:scope[data-ui-button-state~="variant=ghost"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1366
+ :global(:scope[data-appearance="ghost"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1239
1367
  background-color: var(--ui-button-ghost-hover-surface, oklch(from var(--_tone) l c h / 10%));
1240
1368
  border-color: transparent;
1241
1369
  }
1242
- :global(:scope[data-ui-button-state~="variant=ghost"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1370
+ :global(:scope[data-appearance="ghost"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1243
1371
  background-color: var(
1244
1372
  --ui-button-ghost-active-surface,
1245
1373
  color-mix(in oklch, var(--ui-surface), var(--_tone) 3%)
@@ -1256,13 +1384,13 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1256
1384
  var(--ui-focus-halo);
1257
1385
  }
1258
1386
 
1259
- :global(:scope[data-ui-button-state~="variant=solid"]:focus-visible:where([data-hn-ui-button])) {
1387
+ :global(:scope[data-appearance="solid"]:focus-visible:where([data-hn-ui-button])) {
1260
1388
  box-shadow:
1261
1389
  var(--ui-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
1262
1390
  var(--ui-focus-halo);
1263
1391
  }
1264
1392
 
1265
- :global(:is(:scope[data-ui-button-state~="variant=ghost"], :scope[data-ui-button-state~="variant=link"], :scope[data-ui-button-state~="variant=card"]):focus-visible:where([data-hn-ui-button])) {
1393
+ :global(:is(:scope[data-appearance="ghost"], :scope[data-appearance="link"], :scope[data-appearance="card"]):focus-visible:where([data-hn-ui-button])) {
1266
1394
  box-shadow: var(--ui-focus-halo);
1267
1395
  }
1268
1396
  :global(:scope:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"])):where([data-hn-ui-button])) {
@@ -1279,7 +1407,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1279
1407
  :global(:is(:scope[data-ui-button-state~="loading"], :scope[data-ui-button-state~="pending"]):focus-visible:where([data-hn-ui-button])) {
1280
1408
  box-shadow: var(--ui-focus-halo);
1281
1409
  }
1282
- :global(:scope[data-ui-button-state~="variant=ghost"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"])):where([data-hn-ui-button])) {
1410
+ :global(:scope[data-appearance="ghost"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"])):where([data-hn-ui-button])) {
1283
1411
  background-color: var(--ui-disabled-surface);
1284
1412
  border-color: transparent;
1285
1413
  }
@@ -1290,14 +1418,14 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1290
1418
  }
1291
1419
  }
1292
1420
  :global(html[data-ui-input-modality="touch"]
1293
- :scope[data-ui-button-state~="variant=link"]:where([data-hn-ui-button])),
1421
+ :scope[data-appearance="link"]:where([data-hn-ui-button])),
1294
1422
  :global(html[data-ui-input-modality="touch"]
1295
1423
  :scope[data-ui-button-state~="size=xs"]:where([data-hn-ui-button])) {
1296
1424
  position: relative;
1297
1425
  }
1298
1426
 
1299
1427
  :global(html[data-ui-input-modality="touch"]
1300
- :scope[data-ui-button-state~="variant=link"]:where([data-hn-ui-button])::after),
1428
+ :scope[data-appearance="link"]:where([data-hn-ui-button])::after),
1301
1429
  :global(html[data-ui-input-modality="touch"]
1302
1430
  :scope[data-ui-button-state~="size=xs"]:where([data-hn-ui-button])::after) {
1303
1431
  position: absolute;
@@ -1307,7 +1435,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1307
1435
  transform: translate(-50%, -50%);
1308
1436
  content: "";
1309
1437
  }
1310
- :global(:scope[data-ui-button-state~="variant=link"]:where([data-hn-ui-button])) {
1438
+ :global(:scope[data-appearance="link"]:where([data-hn-ui-button])) {
1311
1439
  display: inline !important;
1312
1440
  min-block-size: 0;
1313
1441
  padding: 0 !important;
@@ -1326,24 +1454,24 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1326
1454
  text-decoration-color var(--ui-motion-fast) var(--ui-motion-ease);
1327
1455
  }
1328
1456
 
1329
- :global(:scope[data-ui-button-state~="variant=link"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1457
+ :global(:scope[data-appearance="link"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1330
1458
  color: var(--ui-button-link-hover-text, var(--ui-text-primary));
1331
1459
  text-decoration-color: currentColor;
1332
1460
  background: none;
1333
1461
  transform: none;
1334
1462
  }
1335
1463
 
1336
- :global(:scope[data-ui-button-state~="variant=link"]:active:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1464
+ :global(:scope[data-appearance="link"]:active:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1337
1465
  background: none;
1338
1466
  transform: none;
1339
1467
  }
1340
1468
 
1341
- :global(:scope[data-ui-button-state~="variant=link"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"])):where([data-hn-ui-button])) {
1469
+ :global(:scope[data-appearance="link"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"])):where([data-hn-ui-button])) {
1342
1470
  background: none;
1343
1471
  border-color: transparent;
1344
1472
  }
1345
1473
 
1346
- :global(:scope[data-ui-button-state~="variant=link"]:focus-visible:where([data-hn-ui-button])) {
1474
+ :global(:scope[data-appearance="link"]:focus-visible:where([data-hn-ui-button])) {
1347
1475
  box-shadow: none;
1348
1476
  /* Fallback keeps the ring if the token is missing: an unresolved var() would void the outline. */
1349
1477
  outline: var(--ui-focus-width) solid var(--ui-focus-ring);
package/vue/UiCard.d.ts CHANGED
@@ -23,6 +23,9 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
23
23
  tone: {
24
24
  type: PropType<"neutral" | "accent" | "info" | "success" | "warning" | "danger" | null>;
25
25
  };
26
+ treatment: {
27
+ type: PropType<"standard" | "expressive" | null>;
28
+ };
26
29
  variant: {
27
30
  type: PropType<"outlined" | "subtle" | "elevated" | null>;
28
31
  };
@@ -42,6 +45,9 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
42
45
  tone: {
43
46
  type: PropType<"neutral" | "accent" | "info" | "success" | "warning" | "danger" | null>;
44
47
  };
48
+ treatment: {
49
+ type: PropType<"standard" | "expressive" | null>;
50
+ };
45
51
  variant: {
46
52
  type: PropType<"outlined" | "subtle" | "elevated" | null>;
47
53
  };