@threadlabs/looma 0.37.5 → 0.38.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 (56) hide show
  1. package/components/ui-button/ui-button.html +20 -5
  2. package/components/ui-combobox/ui-combobox.html +24 -3
  3. package/components/ui-combobox/ui-combobox.js +18 -3
  4. package/components/ui-icon-button/ui-icon-button.html +17 -8
  5. package/components/ui-menu-item/ui-menu-item.html +6 -1
  6. package/components/ui-select/ui-select.html +12 -0
  7. package/components/ui-skeleton/ui-skeleton.html +91 -0
  8. package/dist/index.js +1 -1
  9. package/docs/README.md +23 -10
  10. package/docs/catalog.json +246 -31
  11. package/docs/customizer-render.mjs +36 -20
  12. package/docs/customizer.js +76 -25
  13. package/docs/documentation.css +2 -0
  14. package/docs/palette.mjs +3 -3
  15. package/docs/site.mjs +1 -1
  16. package/docs/theme-session.mjs +1 -0
  17. package/docs/theme.mjs +11 -10
  18. package/package.json +2 -2
  19. package/styles/ui-button.css +19 -9
  20. package/styles/ui-combobox.css +40 -2
  21. package/styles/ui-icon-button.css +12 -2
  22. package/styles/ui-menu-item.css +6 -1
  23. package/styles/ui-select.css +9 -0
  24. package/styles/ui-skeleton.css +91 -0
  25. package/theme-system.css +7 -2
  26. package/vanilla/UiButton.js +1 -1
  27. package/vanilla/UiCombobox.d.ts +1 -0
  28. package/vanilla/UiCombobox.js +38 -37
  29. package/vanilla/UiIconButton.d.ts +1 -1
  30. package/vanilla/UiIconButton.js +1 -1
  31. package/vanilla/UiSelect.d.ts +1 -0
  32. package/vanilla/UiSelect.js +7 -7
  33. package/vanilla/UiSkeleton.d.ts +26 -0
  34. package/vanilla/UiSkeleton.js +42 -0
  35. package/vanilla/index.js +1 -0
  36. package/vue/UiButton.vue +30 -12
  37. package/vue/UiCombobox.d.ts +6 -0
  38. package/vue/UiCombobox.vue +70 -6
  39. package/vue/UiIconButton.d.ts +2 -2
  40. package/vue/UiIconButton.vue +23 -18
  41. package/vue/UiMenuItem.vue +6 -1
  42. package/vue/UiSelect.d.ts +6 -0
  43. package/vue/UiSelect.vue +30 -1
  44. package/vue/UiSkeleton.d.ts +37 -0
  45. package/vue/UiSkeleton.js +2 -0
  46. package/vue/UiSkeleton.vue +235 -0
  47. package/vue/chunks/UiButton.js +4 -4
  48. package/vue/chunks/UiCombobox.js +72 -46
  49. package/vue/chunks/UiIconButton.js +6 -7
  50. package/vue/chunks/UiMenuItem.js +1 -1
  51. package/vue/chunks/UiSelect.js +27 -2
  52. package/vue/chunks/UiSkeleton.js +151 -0
  53. package/vue/components.css +197 -25
  54. package/vue/editor/index.js +2 -3
  55. package/vue/index.d.ts +1 -0
  56. package/vue/index.js +2 -1
@@ -1123,8 +1123,6 @@ svg,.arc {
1123
1123
  /* A link is never :enabled, so interactive states test "not unavailable" instead: for a button that
1124
1124
  is exactly :enabled, at the same specificity, and it also matches a link that can be followed. */
1125
1125
 
1126
- /* A neutral card encloses content quietly; ordinary outlines keep their action-tone edge. */
1127
-
1128
1126
  /* Pressed reads as pressed in: the highlight goes, and the shadow moves inside. */
1129
1127
 
1130
1128
  /* Tone is the colour, variant is the volume. Every pairing works: a danger outline is a
@@ -1134,9 +1132,6 @@ svg,.arc {
1134
1132
 
1135
1133
  /* Tints derive from the text colour, not a surface token, so hover and press show on any background. */
1136
1134
 
1137
- /* Pressed, or holding its menu open, a ghost button sinks slightly: a light surface with a faint
1138
- edge and a soft inner shadow. Lighter than hover, so an open menu's trigger never reads as heavy. */
1139
-
1140
1135
  /* A soft halo that transitions in with the other box-shadow changes, layered on the raised shadow. */
1141
1136
 
1142
1137
  /* A loading action stays visually active; only an explicitly disabled action takes the
@@ -1334,6 +1329,11 @@ svg,.arc {
1334
1329
  :scope[data-appearance="card"][data-tone="neutral"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button]) {
1335
1330
  border-color: var(--ui-button-hover-border, var(--ui-border-strong));
1336
1331
  }
1332
+ :scope[data-appearance="card"][aria-pressed="true"]:where([data-hn-ui-button]) {
1333
+ background-color: var(--ui-selection-surface);
1334
+ border-color: var(--ui-selection-border);
1335
+ color: var(--ui-selection-text);
1336
+ }
1337
1337
  :scope:active:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button]) {
1338
1338
  scale: var(--ui-press-scale, 1);
1339
1339
  background-color: var(--ui-button-active-surface, oklch(from var(--_tone) l c h / 18%));
@@ -1373,6 +1373,24 @@ svg,.arc {
1373
1373
  background-color: var(--ui-button-surface, var(--ui-neutral-surface));
1374
1374
  color: var(--ui-button-text, var(--ui-text));
1375
1375
  }
1376
+ :scope[data-tone="neutral"][data-appearance="outline"]:where([data-hn-ui-button]) {
1377
+ border-color: var(--ui-button-border, var(--ui-control-border));
1378
+ background-color: var(--ui-button-surface, transparent);
1379
+ }
1380
+ :scope[data-tone="neutral"][data-appearance="outline"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button]) {
1381
+ border-color: var(
1382
+ --ui-button-hover-border,
1383
+ var(--ui-control-border-hover, var(--ui-control-border))
1384
+ );
1385
+ background-color: var(--ui-button-hover-surface, var(--ui-neutral-hover));
1386
+ }
1387
+ :scope[data-tone="neutral"][data-appearance="outline"]:active:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button]) {
1388
+ border-color: var(
1389
+ --ui-button-hover-border,
1390
+ var(--ui-control-border-hover, var(--ui-control-border))
1391
+ );
1392
+ background-color: var(--ui-button-active-surface, var(--ui-neutral-active));
1393
+ }
1376
1394
  :scope[data-tone="neutral"][data-appearance="solid"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button]) {
1377
1395
  background-color: var(--ui-button-hover-surface, var(--ui-neutral-hover));
1378
1396
  }
@@ -1457,10 +1475,7 @@ svg,.arc {
1457
1475
  border-color: transparent;
1458
1476
  }
1459
1477
  :scope[data-appearance="ghost"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button]) {
1460
- background-color: var(
1461
- --ui-button-ghost-active-surface,
1462
- color-mix(in oklch, var(--ui-surface), var(--_tone) 3%)
1463
- );
1478
+ background-color: var(--ui-button-ghost-active-surface, oklch(from var(--_tone) l c h / 18%));
1464
1479
  border-color: transparent;
1465
1480
  box-shadow:
1466
1481
  inset 0 0 0 1px oklch(from var(--_tone) l c h / 10%),
@@ -2917,6 +2932,21 @@ label:where([data-hn-ui-combobox]) {
2917
2932
  flex: 1 1 auto;
2918
2933
  min-inline-size: 0;
2919
2934
  }
2935
+ .start:where([data-hn-ui-combobox]) {
2936
+ display: flex !important;
2937
+ align-items: center !important;
2938
+ flex: none;
2939
+ padding-inline-start: var(--ui-space-3) !important;
2940
+ }
2941
+ .start:empty:where([data-hn-ui-combobox]) {
2942
+ display: none !important;
2943
+ }
2944
+ :scope[data-ui-combobox-state~="size=sm"] .start:where([data-hn-ui-combobox]) {
2945
+ padding-inline-start: var(--ui-space-2) !important;
2946
+ }
2947
+ :scope[data-ui-combobox-state~="size=lg"] .start:where([data-hn-ui-combobox]) {
2948
+ padding-inline-start: var(--ui-space-4) !important;
2949
+ }
2920
2950
  .help:where([data-hn-ui-combobox]) {
2921
2951
  flex: none;
2922
2952
  display: inline-flex !important;
@@ -2950,6 +2980,10 @@ label:where([data-hn-ui-combobox]) {
2950
2980
  inline-size: var(--ui-icon-size-sm);
2951
2981
  block-size: var(--ui-icon-size-sm);
2952
2982
  }
2983
+ :scope[data-ui-combobox-state~="muted"]
2984
+ input:not(:disabled):where([data-hn-ui-combobox]) {
2985
+ color: var(--ui-text-secondary);
2986
+ }
2953
2987
  input:where([data-hn-ui-combobox])::selection {
2954
2988
  background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
2955
2989
  color: inherit;
@@ -3041,7 +3075,7 @@ input:disabled:where([data-hn-ui-combobox]),button:disabled:where([data-hn-ui-co
3041
3075
  border-radius: var(--_ui-combobox-popup-radius, var(--ui-overlay-radius, var(--ui-radius-md)));
3042
3076
  background: var(
3043
3077
  --_ui-combobox-popup-surface,
3044
- var(--ui-overlay-surface, var(--ui-surface-elevated))
3078
+ var(--ui-material-content, var(--ui-surface-elevated))
3045
3079
  );
3046
3080
  color: var(--ui-text-primary);
3047
3081
  box-shadow: var(
@@ -3237,6 +3271,23 @@ label:where(:scope, :scope *):where([data-hn-ui-combobox]) {
3237
3271
  flex: 1 1 auto;
3238
3272
  min-inline-size: 0;
3239
3273
  }
3274
+ .start:where(:scope, :scope *):where([data-hn-ui-combobox]) {
3275
+ display: flex !important;
3276
+ align-items: center !important;
3277
+ flex: none;
3278
+ padding-inline-start: var(--ui-space-3) !important;
3279
+ }
3280
+ .start:empty:where(:scope, :scope *):where([data-hn-ui-combobox]) {
3281
+ display: none !important;
3282
+ }
3283
+ :where(.ui-combobox)[data-ui-combobox-state~="size=sm"]
3284
+ .start:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox]) {
3285
+ padding-inline-start: var(--ui-space-2) !important;
3286
+ }
3287
+ :where(.ui-combobox)[data-ui-combobox-state~="size=lg"]
3288
+ .start:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox]) {
3289
+ padding-inline-start: var(--ui-space-4) !important;
3290
+ }
3240
3291
  .help:where(:scope, :scope *):where([data-hn-ui-combobox]) {
3241
3292
  flex: none;
3242
3293
  display: inline-flex !important;
@@ -3270,6 +3321,10 @@ label:where(:scope, :scope *):where([data-hn-ui-combobox]) {
3270
3321
  inline-size: var(--ui-icon-size-sm);
3271
3322
  block-size: var(--ui-icon-size-sm);
3272
3323
  }
3324
+ :where(.ui-combobox)[data-ui-combobox-state~="muted"]
3325
+ input:not(:disabled):where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox]) {
3326
+ color: var(--ui-text-secondary);
3327
+ }
3273
3328
  input:where(:not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where(:scope, :scope
3274
3329
  *):where([data-hn-ui-combobox])::selection {
3275
3330
  background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
@@ -3365,7 +3420,7 @@ input:disabled:where(:scope, :scope *):where([data-hn-ui-combobox]),button:disab
3365
3420
  border-radius: var(--_ui-combobox-popup-radius, var(--ui-overlay-radius, var(--ui-radius-md)));
3366
3421
  background: var(
3367
3422
  --_ui-combobox-popup-surface,
3368
- var(--ui-overlay-surface, var(--ui-surface-elevated))
3423
+ var(--ui-material-content, var(--ui-surface-elevated))
3369
3424
  );
3370
3425
  color: var(--ui-text-primary);
3371
3426
  box-shadow: var(
@@ -3752,7 +3807,7 @@ input:disabled:where(:scope, :scope *):where([data-hn-ui-combobox]),button:disab
3752
3807
  inherits: false;
3753
3808
  }
3754
3809
 
3755
- /* Omitted tone retains the existing accent solid; explicit neutral is additive. */
3810
+ /* Neutral actions share the same quiet surface and border roles as fields. */
3756
3811
 
3757
3812
  /* At rest an anticipatory button shows only its guide dot. The icon grows into place when
3758
3813
  proximity, hover, or focus reveals it; the button's hit area and guide remain stable. */
@@ -3879,6 +3934,10 @@ input:disabled:where(:scope, :scope *):where([data-hn-ui-combobox]),button:disab
3879
3934
  :scope[data-tone="neutral"]:where([data-hn-ui-icon-button]) {
3880
3935
  --_tone-highlight: var(--ui-neutral-highlight, none);
3881
3936
  --_tone-glow: var(--ui-neutral-glow, 0 0 transparent);
3937
+ --_icon-button-outline-surface: transparent;
3938
+ --_icon-button-border: var(--ui-control-border);
3939
+ --_icon-button-hover-border: var(--ui-control-border-hover, var(--ui-control-border));
3940
+ --_icon-button-text: var(--ui-text);
3882
3941
  --_icon-button-solid-surface: var(--ui-neutral-surface);
3883
3942
  --_icon-button-solid-hover-surface: var(--ui-neutral-hover);
3884
3943
  --_icon-button-solid-text: var(--ui-text);
@@ -4058,6 +4117,12 @@ html[data-ui-input-modality="touch"] :scope:where([data-hn-ui-icon-button])::aft
4058
4117
  var(--_icon-button-hover-border, var(--ui-control-border-hover, var(--ui-control-border)))
4059
4118
  );
4060
4119
  }
4120
+ :scope[data-tone="neutral"][data-appearance="outline"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button]) {
4121
+ background-color: var(--ui-icon-button-hover-surface, var(--ui-neutral-hover));
4122
+ }
4123
+ :scope[data-tone="neutral"][data-appearance="outline"]:active:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button]) {
4124
+ background-color: var(--ui-icon-button-active-surface, var(--ui-neutral-active));
4125
+ }
4061
4126
  :scope[data-appearance="solid"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button]) {
4062
4127
  background-color: var(
4063
4128
  --ui-icon-button-solid-hover-surface,
@@ -5777,7 +5842,11 @@ footer:empty:where(:scope, :scope *):where([data-hn-ui-dialog]) {
5777
5842
  }
5778
5843
  }
5779
5844
  :scope:is(:hover, :focus-visible):not([aria-disabled="true"]):where([data-hn-ui-menu-item]) {
5780
- background: var(--ui-menu-item-hover-surface, var(--ui-surface-subtle));
5845
+ background: var(--ui-menu-item-hover-surface, var(--ui-accent-subtle));
5846
+ }
5847
+ :scope[aria-checked="true"]:not([aria-disabled="true"]):where([data-hn-ui-menu-item]) {
5848
+ background: var(--ui-selection-surface);
5849
+ color: var(--ui-selection-text);
5781
5850
  }
5782
5851
  :scope:focus-visible:where([data-hn-ui-menu-item]) {
5783
5852
  outline: var(--ui-focus-width) solid var(--ui-focus-ring);
@@ -10077,6 +10146,13 @@ dialog:where([data-hn-ui-search-shell]) {
10077
10146
  background-position: right var(--ui-space-3) center, center;
10078
10147
  background-size: 1.125rem 1.125rem, 100% 100%;
10079
10148
  }
10149
+ :scope[data-ui-select-state~="muted"]:where([data-hn-ui-select]) {
10150
+ color: var(--ui-text-secondary);
10151
+ }
10152
+ :scope[data-ui-select-state~="muted"] :where(:not([data-hn-ui-select])):is(option),:scope[data-ui-select-state~="muted"] :where(:not([data-hn-ui-select])):is(optgroup) {
10153
+ color: var(--ui-text-primary);
10154
+ background-color: var(--ui-control-surface);
10155
+ }
10080
10156
  :scope:hover:not(:focus):not(:disabled):not([aria-invalid="true"]):not(:is(:user-invalid, [data-user-invalid])):where([data-hn-ui-select]) {
10081
10157
  border-color: var(
10082
10158
  --ui-select-border-hover,
@@ -10401,6 +10477,77 @@ dialog:where([data-hn-ui-search-shell]) {
10401
10477
  }
10402
10478
  }
10403
10479
 
10480
+ /* Dimensions belong to this placeholder, never a nested or neighbouring one. */
10481
+ @property --ui-skeleton-width {
10482
+ syntax: "*";
10483
+ inherits: false;
10484
+ }
10485
+ @property --ui-skeleton-height {
10486
+ syntax: "*";
10487
+ inherits: false;
10488
+ }
10489
+ @keyframes ui-skeleton-pulse-ee40410c {
10490
+ 50% {
10491
+ opacity: 0.45;
10492
+ }
10493
+ }
10494
+ @scope (.ui-skeleton) to ([data-hn]) {
10495
+ :scope {
10496
+ display: block !important;
10497
+ position: relative;
10498
+ box-sizing: border-box !important;
10499
+ flex: none;
10500
+ min-inline-size: 0;
10501
+ max-inline-size: 100%;
10502
+ inline-size: var(--ui-skeleton-width, 100%);
10503
+ block-size: var(--ui-skeleton-height, 1lh);
10504
+ margin: 0 !important;
10505
+ font: inherit;
10506
+ }
10507
+ :scope::before {
10508
+ content: "";
10509
+ position: absolute;
10510
+ inset: 0;
10511
+ border-radius: var(--ui-radius-sm);
10512
+ background: color-mix(in srgb, var(--ui-text-primary) 16%, transparent);
10513
+ }
10514
+ :scope[data-ui-skeleton-state~="shape=text"]::before {
10515
+ inset-block: 22%;
10516
+ }
10517
+ :scope[data-ui-skeleton-state~="shape=circle"] {
10518
+ inline-size: var(--ui-skeleton-width, calc(2.5rem + 2 * var(--ui-border-width)));
10519
+ block-size: var(--ui-skeleton-height, auto);
10520
+ aspect-ratio: 1;
10521
+ }
10522
+ :scope[data-ui-skeleton-state~="shape=circle"]::before {
10523
+ border-radius: var(--ui-radius-round);
10524
+ }
10525
+ :scope[data-ui-skeleton-state~="shape=rectangle"] {
10526
+ block-size: var(--ui-skeleton-height, 8rem);
10527
+ }
10528
+ :scope[data-ui-skeleton-state~="shape=rectangle"]::before {
10529
+ border-radius: var(--ui-radius-md);
10530
+ }
10531
+ :scope[data-ui-skeleton-state~="animated"]::before {
10532
+ animation: ui-skeleton-pulse-ee40410c 1.6s ease-in-out infinite;
10533
+ }
10534
+ @media (prefers-reduced-motion: reduce) {
10535
+ :scope[data-ui-skeleton-state~="animated"]::before {
10536
+ animation: none;
10537
+ }
10538
+ }
10539
+ @media (forced-colors: active) {
10540
+ :scope::before {
10541
+ background: CanvasText;
10542
+ opacity: 0.2;
10543
+ animation: none;
10544
+ }
10545
+ }
10546
+ :scope[hidden] {
10547
+ display: none !important;
10548
+ }
10549
+ }
10550
+
10404
10551
  @scope (.ui-slider) to ([data-hn]) {
10405
10552
  :scope {
10406
10553
  display: grid !important;
@@ -13679,7 +13826,6 @@ html[data-ui-input-modality="touch"]
13679
13826
  background-color: var(--ui-button-hover-surface, oklch(from var(--_tone) l c h / 12%));
13680
13827
  }
13681
13828
 
13682
- /* A neutral card encloses content quietly; ordinary outlines keep their action-tone edge. */
13683
13829
  :scope:where([data-component~="ui-button"])[data-appearance="card"][data-tone="neutral"] {
13684
13830
  border-color: var(--ui-button-border, var(--ui-border));
13685
13831
  }
@@ -13688,6 +13834,12 @@ html[data-ui-input-modality="touch"]
13688
13834
  border-color: var(--ui-button-hover-border, var(--ui-border-strong));
13689
13835
  }
13690
13836
 
13837
+ :scope:where([data-component~="ui-button"])[data-appearance="card"][aria-pressed="true"] {
13838
+ background-color: var(--ui-selection-surface);
13839
+ border-color: var(--ui-selection-border);
13840
+ color: var(--ui-selection-text);
13841
+ }
13842
+
13691
13843
  /* Pressed reads as pressed in: the highlight goes, and the shadow moves inside. */
13692
13844
  :scope:where([data-component~="ui-button"]):active:not(:disabled, [aria-disabled="true"]) {
13693
13845
  scale: var(--ui-press-scale, 1);
@@ -13735,6 +13887,18 @@ html[data-ui-input-modality="touch"]
13735
13887
  background-color: var(--ui-button-surface, var(--ui-neutral-surface));
13736
13888
  color: var(--ui-button-text, var(--ui-text));
13737
13889
  }
13890
+ :scope:where([data-component~="ui-button"])[data-tone="neutral"][data-appearance="outline"] {
13891
+ border-color: var(--ui-button-border, var(--ui-control-border));
13892
+ background-color: var(--ui-button-surface, transparent);
13893
+ }
13894
+ :scope:where([data-component~="ui-button"])[data-tone="neutral"][data-appearance="outline"]:hover:not(:disabled, [aria-disabled="true"]) {
13895
+ border-color: var(--ui-button-hover-border, var(--ui-control-border-hover, var(--ui-control-border)));
13896
+ background-color: var(--ui-button-hover-surface, var(--ui-neutral-hover));
13897
+ }
13898
+ :scope:where([data-component~="ui-button"])[data-tone="neutral"][data-appearance="outline"]:active:not(:disabled, [aria-disabled="true"]) {
13899
+ border-color: var(--ui-button-hover-border, var(--ui-control-border-hover, var(--ui-control-border)));
13900
+ background-color: var(--ui-button-active-surface, var(--ui-neutral-active));
13901
+ }
13738
13902
  :scope:where([data-component~="ui-button"])[data-tone="neutral"][data-appearance="solid"]:hover:not(:disabled, [aria-disabled="true"]) {
13739
13903
  background-color: var(--ui-button-hover-surface, var(--ui-neutral-hover));
13740
13904
  }
@@ -13822,10 +13986,8 @@ html[data-ui-input-modality="touch"]
13822
13986
  border-color: transparent;
13823
13987
  }
13824
13988
 
13825
- /* Pressed, or holding its menu open, a ghost button sinks slightly: a light surface with a faint
13826
- edge and a soft inner shadow. Lighter than hover, so an open menu's trigger never reads as heavy. */
13827
13989
  :scope:where([data-component~="ui-button"])[data-appearance="ghost"]:is(:active, [aria-expanded="true"]):not(:disabled, [aria-disabled="true"]) {
13828
- background-color: var(--ui-button-ghost-active-surface, color-mix(in oklch, var(--ui-surface), var(--_tone) 3%));
13990
+ background-color: var(--ui-button-ghost-active-surface, oklch(from var(--_tone) l c h / 18%));
13829
13991
  border-color: transparent;
13830
13992
  box-shadow: inset 0 0 0 1px oklch(from var(--_tone) l c h / 10%), inset 0 1px 2px oklch(from var(--_tone) l c h / 8%);
13831
13993
  }
@@ -13959,8 +14121,6 @@ html[data-ui-input-modality="touch"]
13959
14121
  /* A link is never :enabled, so interactive states test "not unavailable" instead: for a button that
13960
14122
  is exactly :enabled, at the same specificity, and it also matches a link that can be followed. */
13961
14123
 
13962
- /* A neutral card encloses content quietly; ordinary outlines keep their action-tone edge. */
13963
-
13964
14124
  /* Pressed reads as pressed in: the highlight goes, and the shadow moves inside. */
13965
14125
 
13966
14126
  /* Tone is the colour, variant is the volume. Every pairing works: a danger outline is a
@@ -13970,9 +14130,6 @@ html[data-ui-input-modality="touch"]
13970
14130
 
13971
14131
  /* Tints derive from the text colour, not a surface token, so hover and press show on any background. */
13972
14132
 
13973
- /* Pressed, or holding its menu open, a ghost button sinks slightly: a light surface with a faint
13974
- edge and a soft inner shadow. Lighter than hover, so an open menu's trigger never reads as heavy. */
13975
-
13976
14133
  /* A soft halo that transitions in with the other box-shadow changes, layered on the raised shadow. */
13977
14134
 
13978
14135
  /* A loading action stays visually active; only an explicitly disabled action takes the
@@ -14486,10 +14643,14 @@ html[data-ui-input-modality="touch"]
14486
14643
  color: var(--_icon-button-text);
14487
14644
  }
14488
14645
 
14489
- /* Omitted tone retains the existing accent solid; explicit neutral is additive. */
14646
+ /* Neutral actions share the same quiet surface and border roles as fields. */
14490
14647
  :scope:where([data-component~="ui-icon-button"])[data-tone="neutral"] {
14491
14648
  --_tone-highlight: var(--ui-neutral-highlight, none);
14492
14649
  --_tone-glow: var(--ui-neutral-glow, 0 0 transparent);
14650
+ --_icon-button-outline-surface: transparent;
14651
+ --_icon-button-border: var(--ui-control-border);
14652
+ --_icon-button-hover-border: var(--ui-control-border-hover, var(--ui-control-border));
14653
+ --_icon-button-text: var(--ui-text);
14493
14654
  --_icon-button-solid-surface: var(--ui-neutral-surface);
14494
14655
  --_icon-button-solid-hover-surface: var(--ui-neutral-hover);
14495
14656
  --_icon-button-solid-text: var(--ui-text);
@@ -14677,6 +14838,12 @@ html[data-ui-input-modality="touch"]
14677
14838
  :scope:where([data-component~="ui-icon-button"])[data-appearance="outline"]:hover:enabled:not([aria-disabled="true"]) {
14678
14839
  border-color: var(--ui-icon-button-hover-border, var(--_icon-button-hover-border, var(--ui-control-border-hover, var(--ui-control-border))));
14679
14840
  }
14841
+ :scope:where([data-component~="ui-icon-button"])[data-tone="neutral"][data-appearance="outline"]:hover:enabled:not([aria-disabled="true"]) {
14842
+ background-color: var(--ui-icon-button-hover-surface, var(--ui-neutral-hover));
14843
+ }
14844
+ :scope:where([data-component~="ui-icon-button"])[data-tone="neutral"][data-appearance="outline"]:active:enabled:not([aria-disabled="true"]) {
14845
+ background-color: var(--ui-icon-button-active-surface, var(--ui-neutral-active));
14846
+ }
14680
14847
 
14681
14848
  :scope:where([data-component~="ui-icon-button"])[data-appearance="solid"]:hover:enabled:not([aria-disabled="true"]) {
14682
14849
  background-color: var(--ui-icon-button-solid-hover-surface, var(--_icon-button-solid-hover-surface, var(--ui-accent-hover)));
@@ -14801,7 +14968,7 @@ html[data-ui-input-modality="touch"]
14801
14968
  @scope ([data-component~="ui-icon-button"]) to ([data-component]) {
14802
14969
  /* This component's hooks style the element they are set on, and never a nested one. */
14803
14970
 
14804
- /* Omitted tone retains the existing accent solid; explicit neutral is additive. */
14971
+ /* Neutral actions share the same quiet surface and border roles as fields. */
14805
14972
 
14806
14973
  /* At rest an anticipatory button shows only its guide dot. The icon grows into place when
14807
14974
  proximity, hover, or focus reveals it; the button's hit area and guide remain stable. */
@@ -15307,7 +15474,12 @@ html[data-ui-input-modality="touch"]
15307
15474
  }
15308
15475
 
15309
15476
  :scope:where([data-component~="ui-menu-item"]):is(:hover, :focus-visible):not([aria-disabled="true"]) {
15310
- background: var(--ui-menu-item-hover-surface, var(--ui-surface-subtle));
15477
+ background: var(--ui-menu-item-hover-surface, var(--ui-accent-subtle));
15478
+ }
15479
+
15480
+ :scope:where([data-component~="ui-menu-item"])[aria-checked="true"]:not([aria-disabled="true"]) {
15481
+ background: var(--ui-selection-surface);
15482
+ color: var(--ui-selection-text);
15311
15483
  }
15312
15484
 
15313
15485
  :scope:where([data-component~="ui-menu-item"]):focus-visible {
@@ -3756,7 +3756,7 @@ var D$18 = {
3756
3756
  "warning",
3757
3757
  "info"
3758
3758
  ],
3759
- "default": "accent",
3759
+ "default": "neutral",
3760
3760
  c: checkFormat("keyword", keywordFormat),
3761
3761
  t: "keyword",
3762
3762
  j: 0,
@@ -7666,7 +7666,6 @@ var D$13 = {
7666
7666
  "tone": {
7667
7667
  "required": false,
7668
7668
  "values": [
7669
- "auto",
7670
7669
  "accent",
7671
7670
  "neutral",
7672
7671
  "danger",
@@ -7674,7 +7673,7 @@ var D$13 = {
7674
7673
  "warning",
7675
7674
  "info"
7676
7675
  ],
7677
- "default": "auto",
7676
+ "default": "neutral",
7678
7677
  c: checkFormat("keyword", keywordFormat),
7679
7678
  t: "keyword",
7680
7679
  j: 0,
package/vue/index.d.ts CHANGED
@@ -71,6 +71,7 @@ export { default as Section } from "./UiSection.js";
71
71
  export { default as Select } from "./UiSelect.js";
72
72
  export { default as Separator } from "./UiSeparator.js";
73
73
  export { default as Sidebar } from "./UiSidebar.js";
74
+ export { default as Skeleton } from "./UiSkeleton.js";
74
75
  export { default as Slider } from "./UiSlider.js";
75
76
  export { default as Spinner } from "./UiSpinner.js";
76
77
  export { default as Stack } from "./UiStack.js";
package/vue/index.js CHANGED
@@ -77,6 +77,7 @@ import { t as UiSection_default } from "./chunks/UiSection.js";
77
77
  import { t as UiSelect_default } from "./chunks/UiSelect.js";
78
78
  import { t as UiSeparator_default } from "./chunks/UiSeparator.js";
79
79
  import { t as UiSidebar_default } from "./chunks/UiSidebar.js";
80
+ import { t as UiSkeleton_default } from "./chunks/UiSkeleton.js";
80
81
  import { t as UiSlider_default } from "./chunks/UiSlider.js";
81
82
  import { t as UiStatusMessage_default } from "./chunks/UiStatusMessage.js";
82
83
  import { t as UiSwitch_default } from "./chunks/UiSwitch.js";
@@ -89,4 +90,4 @@ import { t as UiTopBar_default } from "./chunks/UiTopBar.js";
89
90
  import { t as UiTree_default } from "./chunks/UiTree.js";
90
91
  import { t as UiTreeItem_default } from "./chunks/UiTreeItem.js";
91
92
  import { trackInputModality } from "@threadlabs/looma/components/shared/input-modality.js";
92
- export { UiActionBar_default as ActionBar, UiAffordanceScope_default as AffordanceScope, UiAvatar_default as Avatar, UiAvatarGroup_default as AvatarGroup, UiBadge_default as Badge, UiBreadcrumbItem_default as BreadcrumbItem, UiBreadcrumbs_default as Breadcrumbs, UiButton_default as Button, UiCallout_default as Callout, UiCard_default as Card, UiCheckbox_default as Checkbox, UiCluster_default as Cluster, UiColorPicker_default as ColorPicker, UiCombobox_default as Combobox, UiContainer_default as Container, UiContextMenu_default as ContextMenu, UiCover_default as Cover, UiCurveEditor_default as CurveEditor, UiCycleButton_default as CycleButton, UiDescriptionItem_default as DescriptionItem, UiDescriptionList_default as DescriptionList, UiDialog_default as Dialog, UiDisclosure_default as Disclosure, UiEditable_default as Editable, UiEditorBlockActions_default as EditorBlockActions, UiEditorChipEditor_default as EditorChipEditor, UiEditorCodeLanguage_default as EditorCodeLanguage, UiEditorFootnoteEditor_default as EditorFootnoteEditor, UiEditorImageToolbar_default as EditorImageToolbar, UiEditorInsertTableGrid_default as EditorInsertTableGrid, UiEditorLinkCard_default as EditorLinkCard, UiEditorLinkForm_default as EditorLinkForm, UiEditorMentionMenu_default as EditorMentionMenu, UiEditorMentionMenuItem_default as EditorMentionMenuItem, UiEditorSlashMenu_default as EditorSlashMenu, UiEditorSlashMenuGroup_default as EditorSlashMenuGroup, UiEditorSlashMenuItem_default as EditorSlashMenuItem, UiEditorSurface_default as EditorSurface, UiEditorTableContextMenu_default as EditorTableContextMenu, UiEditorTableOverlay_default as EditorTableOverlay, UiEditorTableToolbar_default as EditorTableToolbar, UiEditorToolbar_default as EditorToolbar, UiFloatingActionButton_default as FloatingActionButton, UiFormField_default as FormField, UiGrid_default as Grid, UiIcon_default as Icon, UiIconButton_default as IconButton, UiImage_default as Image, UiInput_default as Input, UiInputGroup_default as InputGroup, UiLightEditor_default as LightEditor, UiList_default as List, UiListItem_default as ListItem, UiListbox_default as Listbox, UiMenu_default as Menu, UiMenuGroup_default as MenuGroup, UiMenuItem_default as MenuItem, UiMeter_default as Meter, UiNavItem_default as NavItem, UiNumberInput_default as NumberInput, UiPageHeader_default as PageHeader, UiPagination_default as Pagination, UiPopover_default as Popover, UiRadio_default as Radio, UiRadioGroup_default as RadioGroup, UiReel_default as Reel, UiScrollArea_default as ScrollArea, UiSearchResultRow_default as SearchResultRow, UiSearchShell_default as SearchShell, UiSection_default as Section, UiSelect_default as Select, UiSeparator_default as Separator, UiSidebar_default as Sidebar, UiSlider_default as Slider, UiSpinner_default as Spinner, UiStack_default as Stack, UiStatusMessage_default as StatusMessage, UiSwatch_default as Swatch, UiSwitch_default as Switch, UiSwitcher_default as Switcher, UiTable_default as Table, UiTabs_default as Tabs, UiText_default as Text, UiTextarea_default as Textarea, UiToast_default as Toast, UiToastRegion_default as ToastRegion, UiTooltip_default as Tooltip, UiTopBar_default as TopBar, UiTree_default as Tree, UiTreeItem_default as TreeItem, trackInputModality };
93
+ export { UiActionBar_default as ActionBar, UiAffordanceScope_default as AffordanceScope, UiAvatar_default as Avatar, UiAvatarGroup_default as AvatarGroup, UiBadge_default as Badge, UiBreadcrumbItem_default as BreadcrumbItem, UiBreadcrumbs_default as Breadcrumbs, UiButton_default as Button, UiCallout_default as Callout, UiCard_default as Card, UiCheckbox_default as Checkbox, UiCluster_default as Cluster, UiColorPicker_default as ColorPicker, UiCombobox_default as Combobox, UiContainer_default as Container, UiContextMenu_default as ContextMenu, UiCover_default as Cover, UiCurveEditor_default as CurveEditor, UiCycleButton_default as CycleButton, UiDescriptionItem_default as DescriptionItem, UiDescriptionList_default as DescriptionList, UiDialog_default as Dialog, UiDisclosure_default as Disclosure, UiEditable_default as Editable, UiEditorBlockActions_default as EditorBlockActions, UiEditorChipEditor_default as EditorChipEditor, UiEditorCodeLanguage_default as EditorCodeLanguage, UiEditorFootnoteEditor_default as EditorFootnoteEditor, UiEditorImageToolbar_default as EditorImageToolbar, UiEditorInsertTableGrid_default as EditorInsertTableGrid, UiEditorLinkCard_default as EditorLinkCard, UiEditorLinkForm_default as EditorLinkForm, UiEditorMentionMenu_default as EditorMentionMenu, UiEditorMentionMenuItem_default as EditorMentionMenuItem, UiEditorSlashMenu_default as EditorSlashMenu, UiEditorSlashMenuGroup_default as EditorSlashMenuGroup, UiEditorSlashMenuItem_default as EditorSlashMenuItem, UiEditorSurface_default as EditorSurface, UiEditorTableContextMenu_default as EditorTableContextMenu, UiEditorTableOverlay_default as EditorTableOverlay, UiEditorTableToolbar_default as EditorTableToolbar, UiEditorToolbar_default as EditorToolbar, UiFloatingActionButton_default as FloatingActionButton, UiFormField_default as FormField, UiGrid_default as Grid, UiIcon_default as Icon, UiIconButton_default as IconButton, UiImage_default as Image, UiInput_default as Input, UiInputGroup_default as InputGroup, UiLightEditor_default as LightEditor, UiList_default as List, UiListItem_default as ListItem, UiListbox_default as Listbox, UiMenu_default as Menu, UiMenuGroup_default as MenuGroup, UiMenuItem_default as MenuItem, UiMeter_default as Meter, UiNavItem_default as NavItem, UiNumberInput_default as NumberInput, UiPageHeader_default as PageHeader, UiPagination_default as Pagination, UiPopover_default as Popover, UiRadio_default as Radio, UiRadioGroup_default as RadioGroup, UiReel_default as Reel, UiScrollArea_default as ScrollArea, UiSearchResultRow_default as SearchResultRow, UiSearchShell_default as SearchShell, UiSection_default as Section, UiSelect_default as Select, UiSeparator_default as Separator, UiSidebar_default as Sidebar, UiSkeleton_default as Skeleton, UiSlider_default as Slider, UiSpinner_default as Spinner, UiStack_default as Stack, UiStatusMessage_default as StatusMessage, UiSwatch_default as Swatch, UiSwitch_default as Switch, UiSwitcher_default as Switcher, UiTable_default as Table, UiTabs_default as Tabs, UiText_default as Text, UiTextarea_default as Textarea, UiToast_default as Toast, UiToastRegion_default as ToastRegion, UiTooltip_default as Tooltip, UiTopBar_default as TopBar, UiTree_default as Tree, UiTreeItem_default as TreeItem, trackInputModality };