@duskmoon-dev/core 1.19.2 → 1.19.4

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 (122) hide show
  1. package/README.md +1 -1
  2. package/dist/base.css +484 -0
  3. package/dist/components/accordion.css +33 -9
  4. package/dist/components/autocomplete.css +67 -13
  5. package/dist/components/avatar.css +39 -15
  6. package/dist/components/badge.css +15 -3
  7. package/dist/components/card.css +12 -0
  8. package/dist/components/carousel.css +28 -0
  9. package/dist/components/chat.css +15 -11
  10. package/dist/components/checkbox.css +83 -13
  11. package/dist/components/collapse.css +67 -16
  12. package/dist/components/countdown.css +22 -0
  13. package/dist/components/datepicker.css +76 -0
  14. package/dist/components/diff.css +33 -0
  15. package/dist/components/file-input.css +107 -0
  16. package/dist/components/filter-group.css +452 -0
  17. package/dist/components/footer.css +48 -0
  18. package/dist/components/form-group.css +95 -204
  19. package/dist/components/form.css +1551 -421
  20. package/dist/components/hero.css +57 -0
  21. package/dist/components/index.css +7657 -7321
  22. package/dist/components/indicator.css +63 -0
  23. package/dist/components/input.css +114 -31
  24. package/dist/components/join.css +70 -0
  25. package/dist/components/kbd.css +28 -0
  26. package/dist/components/list.css +22 -3
  27. package/dist/components/mask.css +38 -0
  28. package/dist/components/otp-input.css +124 -6
  29. package/dist/components/radio.css +70 -0
  30. package/dist/components/range.css +41 -0
  31. package/dist/components/rating.css +39 -12
  32. package/dist/components/select.css +74 -0
  33. package/dist/components/sidebar-layout.css +66 -0
  34. package/dist/components/stack.css +56 -0
  35. package/dist/components/stat.css +40 -0
  36. package/dist/components/switch.css +70 -0
  37. package/dist/components/table.css +8 -0
  38. package/dist/components/textarea.css +74 -0
  39. package/dist/components/timeline.css +40 -25
  40. package/dist/components/toggle-switch.css +165 -0
  41. package/dist/components/toggle.css +198 -32
  42. package/dist/components/validator.css +66 -0
  43. package/dist/effects/aura.css +22 -0
  44. package/dist/effects/hover-3d.css +8 -0
  45. package/dist/effects/hover-gallery.css +14 -0
  46. package/dist/effects/index.css +65 -0
  47. package/dist/effects/text-rotate.css +16 -0
  48. package/dist/esm/components/accordion.js +33 -9
  49. package/dist/esm/components/autocomplete.js +67 -13
  50. package/dist/esm/components/avatar.js +39 -15
  51. package/dist/esm/components/badge.js +15 -3
  52. package/dist/esm/components/card.js +12 -0
  53. package/dist/esm/components/carousel.d.ts +5 -0
  54. package/dist/esm/components/carousel.js +37 -0
  55. package/dist/esm/components/chat.js +15 -11
  56. package/dist/esm/components/checkbox.js +84 -14
  57. package/dist/esm/components/collapse.js +67 -16
  58. package/dist/esm/components/countdown.d.ts +5 -0
  59. package/dist/esm/components/countdown.js +31 -0
  60. package/dist/esm/components/datepicker.js +77 -1
  61. package/dist/esm/components/diff.d.ts +5 -0
  62. package/dist/esm/components/diff.js +42 -0
  63. package/dist/esm/components/file-input.d.ts +5 -0
  64. package/dist/esm/components/file-input.js +116 -0
  65. package/dist/esm/components/filter-group.d.ts +5 -0
  66. package/dist/esm/components/filter-group.js +461 -0
  67. package/dist/esm/components/footer.d.ts +5 -0
  68. package/dist/esm/components/footer.js +57 -0
  69. package/dist/esm/components/form-group.js +96 -205
  70. package/dist/esm/components/form.js +1539 -409
  71. package/dist/esm/components/hero.d.ts +5 -0
  72. package/dist/esm/components/hero.js +66 -0
  73. package/dist/esm/components/indicator.d.ts +5 -0
  74. package/dist/esm/components/indicator.js +72 -0
  75. package/dist/esm/components/input.js +115 -32
  76. package/dist/esm/components/join.d.ts +5 -0
  77. package/dist/esm/components/join.js +79 -0
  78. package/dist/esm/components/kbd.d.ts +5 -0
  79. package/dist/esm/components/kbd.js +37 -0
  80. package/dist/esm/components/list.js +22 -3
  81. package/dist/esm/components/mask.d.ts +5 -0
  82. package/dist/esm/components/mask.js +47 -0
  83. package/dist/esm/components/otp-input.js +125 -7
  84. package/dist/esm/components/radio.js +71 -1
  85. package/dist/esm/components/range.d.ts +5 -0
  86. package/dist/esm/components/range.js +50 -0
  87. package/dist/esm/components/rating.js +39 -12
  88. package/dist/esm/components/select.js +75 -1
  89. package/dist/esm/components/sidebar-layout.d.ts +5 -0
  90. package/dist/esm/components/sidebar-layout.js +75 -0
  91. package/dist/esm/components/stack.d.ts +5 -0
  92. package/dist/esm/components/stack.js +65 -0
  93. package/dist/esm/components/stat.d.ts +5 -0
  94. package/dist/esm/components/stat.js +49 -0
  95. package/dist/esm/components/switch.js +71 -1
  96. package/dist/esm/components/table.js +8 -0
  97. package/dist/esm/components/textarea.js +75 -1
  98. package/dist/esm/components/timeline.js +40 -25
  99. package/dist/esm/components/toggle-switch.d.ts +5 -0
  100. package/dist/esm/components/toggle-switch.js +174 -0
  101. package/dist/esm/components/toggle.js +198 -32
  102. package/dist/esm/components/validator.d.ts +5 -0
  103. package/dist/esm/components/validator.js +75 -0
  104. package/dist/esm/effects/aura.d.ts +5 -0
  105. package/dist/esm/effects/aura.js +31 -0
  106. package/dist/esm/effects/hover-3d.d.ts +5 -0
  107. package/dist/esm/effects/hover-3d.js +17 -0
  108. package/dist/esm/effects/hover-gallery.d.ts +5 -0
  109. package/dist/esm/effects/hover-gallery.js +23 -0
  110. package/dist/esm/effects/index.d.ts +5 -0
  111. package/dist/esm/effects/index.js +74 -0
  112. package/dist/esm/effects/text-rotate.d.ts +5 -0
  113. package/dist/esm/effects/text-rotate.js +25 -0
  114. package/dist/index.css +8324 -7989
  115. package/dist/index.min.css +1 -1
  116. package/dist/standalone/duskmoonui-themes.css +1 -1
  117. package/dist/standalone/duskmoonui.css +9103 -8759
  118. package/dist/standalone/duskmoonui.js +12 -13
  119. package/dist/standalone/duskmoonui.mjs +12 -13
  120. package/dist/types/types/plugin.d.ts +1 -1
  121. package/dist/types/types/plugin.d.ts.map +1 -1
  122. package/package.json +140 -1
@@ -0,0 +1,66 @@
1
+ /** Opt-in native presentation. Applications own errors, messages and announcements. */
2
+ @layer components {
3
+ /* Compatibility wrapper states are intentionally immediate. */
4
+ :is(.form-group-info, .form-control.info) { --dm-validation-color: var(--color-info); }
5
+ :is(.form-group-warning, .form-control.warning) { --dm-validation-color: var(--color-warning); }
6
+ :is(.form-group-success, .form-control.success) { --dm-validation-color: var(--color-success); }
7
+
8
+ :is(.input, .select, .textarea, .checkbox, .radio, .switch, .toggle, .file-input, .otp-input-field, .otp-code, .datepicker-input):is(.validate :valid, .validate:valid, .validator.validator-success:user-valid):not([aria-invalid="true"]):not(:where(.form-group-error *, .form-control.error *)):not(:disabled) {
9
+ --dm-validation-color: var(--color-success);
10
+ --dm-validation-content: var(--color-success-content);
11
+ }
12
+
13
+ :is(.input, .select, .textarea, .checkbox, .radio, .switch, .toggle, .file-input, .otp-input-field, .otp-code, .datepicker-input):is(.validate :invalid, .validate:invalid, .validator:user-invalid):not(:disabled) {
14
+ --dm-validation-color: var(--color-error);
15
+ --dm-validation-content: var(--color-error-content);
16
+ }
17
+
18
+ :is(.form-group-error, .form-control.error) {
19
+ --dm-validation-color: var(--color-error);
20
+ --dm-validation-content: var(--color-error-content);
21
+ }
22
+
23
+ /* Higher specificity than native states, including server-invalid + user-valid. */
24
+ :is(.input, .select, .textarea, .checkbox, .radio, .switch, .toggle, .file-input, .otp-input-field, .otp-code, .datepicker-input):is([aria-invalid="true"], .form-group-error *, .form-control.error *):not(:disabled):is(:focus, :not(:focus)) {
25
+ --dm-validation-color: var(--color-error);
26
+ --dm-validation-content: var(--color-error-content);
27
+ }
28
+
29
+ /* This shared selector wins over filled/ghost focus and semantic modifiers. */
30
+ :is(.input, .select, .textarea, .checkbox, .radio, .switch, .toggle, .file-input, .otp-input-field, .otp-code, .datepicker-input):is([aria-invalid="true"], .validator:user-invalid, .validator.validator-success:user-valid, .validate :invalid, .validate :valid, .validate:invalid, .validate:valid, .form-group-error *, .form-group-success *, .form-group-warning *, .form-group-info *, .form-control.error *, .form-control.success *, .form-control.warning *, .form-control.info *):not(:disabled) {
31
+ color: var(--dm-validation-color);
32
+ border-color: var(--dm-validation-color);
33
+ --checkbox-color: var(--dm-validation-color);
34
+ --radio-color: var(--dm-validation-color);
35
+ --switch-color: var(--dm-validation-color);
36
+ --switch-content-color: var(--dm-validation-content, var(--color-primary-content));
37
+ --toggle-color: var(--dm-validation-color);
38
+ }
39
+
40
+ :is(.input, .select, .textarea, .checkbox, .radio, .switch, .toggle, .file-input, .otp-input-field, .otp-code, .datepicker-input):is([aria-invalid="true"], .validator:user-invalid, .validator.validator-success:user-valid, .validate :invalid, .validate :valid, .validate:invalid, .validate:valid, .form-group-error *, .form-group-success *, .form-group-warning *, .form-group-info *, .form-control.error *, .form-control.success *, .form-control.warning *, .form-control.info *):not(:disabled):focus {
41
+ border-color: var(--dm-validation-color);
42
+ box-shadow: 0 0 0 3px color-mix(in oklch, var(--dm-validation-color) 20%, transparent);
43
+ }
44
+
45
+ :is(.form-group-error, .form-control.error) :is(.form-label, .label-text) { color: var(--color-error); }
46
+ :is(.form-group-success, .form-control.success) :is(.form-label, .label-text) { color: var(--color-success); }
47
+ :is(.form-group-warning, .form-control.warning) :is(.form-label, .label-text) { color: var(--color-warning); }
48
+ :is(.form-group-info, .form-control.info) :is(.form-label, .label-text) { color: var(--color-info); }
49
+
50
+ .validator-hint { font-size: 0.75rem; color: var(--color-on-surface-variant); }
51
+ .validator-error { display: none; font-size: 0.75rem; color: var(--color-error); }
52
+ /* Keep OTP actions stationary when blur reveals an error during a click. */
53
+ .otp-code ~ .validator-error { display: block; visibility: hidden; }
54
+ :is(.form-group, .form-control):has(:is([aria-invalid="true"], .validator:user-invalid, .validate :invalid, .validate:invalid):not(:disabled)) > .validator-error,
55
+ :is(.form-group-error, .form-control.error) > .validator-error { display: block; visibility: visible; }
56
+
57
+ @media (forced-colors: active) {
58
+ :is(input, select, textarea):is(.input, .select, .textarea, .checkbox, .radio, .switch, .toggle, .file-input, .otp-input-field, .otp-code, .datepicker-input):focus-visible {
59
+ outline: 2px solid Highlight;
60
+ outline-offset: 2px;
61
+ }
62
+ input:is(.checkbox, .radio, .switch, .toggle) { appearance: auto; }
63
+ input:is(.checkbox, .radio, .switch, .toggle)::before,
64
+ input:is(.checkbox, .radio, .switch, .toggle)::after { content: none; }
65
+ }
66
+ }
@@ -0,0 +1,22 @@
1
+ @layer components {
2
+ .aura {
3
+ position: relative;
4
+ isolation: isolate;
5
+ border-radius: var(--radius-md);
6
+ outline: 1px solid var(--color-primary);
7
+ }
8
+ .aura::before {
9
+ content: '';
10
+ position: absolute;
11
+ inset: 0;
12
+ z-index: -1;
13
+ border-radius: inherit;
14
+ box-shadow: 0 0 1rem color-mix(in oklch, var(--color-primary) 35%, transparent);
15
+ pointer-events: none;
16
+ }
17
+ @media (prefers-reduced-motion: no-preference) {
18
+ .aura-animated::before { animation: dm-aura 4s ease-in-out infinite; }
19
+ }
20
+ @keyframes dm-aura { 50% { opacity: 0.4; } }
21
+ @media print { .aura::before { display: none; } }
22
+ }
@@ -0,0 +1,8 @@
1
+ @layer components {
2
+ .hover-3d { border-radius: var(--radius-md); }
3
+ @media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
4
+ .hover-3d { transition: transform 200ms ease; }
5
+ .hover-3d:hover:not(:focus-within) { transform: perspective(60rem) rotateX(var(--hover-3d-x, 2deg)) rotateY(var(--hover-3d-y, -2deg)); }
6
+ }
7
+ @media print { .hover-3d { transform: none; } }
8
+ }
@@ -0,0 +1,14 @@
1
+ @layer components {
2
+ .hover-gallery { display: grid; gap: 0.5rem; min-inline-size: 0; color: var(--color-on-surface); }
3
+ .hover-gallery-stage { aspect-ratio: var(--hover-gallery-ratio, 4 / 3); overflow: hidden; border-radius: var(--radius-md); }
4
+ .hover-gallery-stage img { inline-size: 100%; block-size: 100%; object-fit: cover; }
5
+ .hover-gallery-controls { display: flex; flex-wrap: wrap; gap: 0.5rem; }
6
+ .hover-gallery-controls > button { border: 1px solid currentColor; color: inherit; background: var(--color-surface-container); padding: 0.25rem; border-radius: var(--radius-sm); cursor: pointer; }
7
+ .hover-gallery-controls img { display: block; inline-size: 3rem; block-size: 3rem; object-fit: cover; }
8
+ .hover-gallery-controls > button[aria-pressed="true"] { color: var(--color-primary); outline: 2px solid currentColor; }
9
+ .hover-gallery-controls > button:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
10
+ @media (hover: hover) and (prefers-reduced-motion: no-preference) {
11
+ .hover-gallery-controls > button:hover { background: var(--color-primary-container); }
12
+ }
13
+ @media print { .hover-gallery-controls { display: none; } }
14
+ }
@@ -0,0 +1,65 @@
1
+ /* Explicitly opt-in. Not imported by core or components/index.css. */
2
+ @layer components {
3
+ .aura {
4
+ position: relative;
5
+ isolation: isolate;
6
+ border-radius: var(--radius-md);
7
+ outline: 1px solid var(--color-primary);
8
+ }
9
+ .aura::before {
10
+ content: '';
11
+ position: absolute;
12
+ inset: 0;
13
+ z-index: -1;
14
+ border-radius: inherit;
15
+ box-shadow: 0 0 1rem color-mix(in oklch, var(--color-primary) 35%, transparent);
16
+ pointer-events: none;
17
+ }
18
+ @media (prefers-reduced-motion: no-preference) {
19
+ .aura-animated::before { animation: dm-aura 4s ease-in-out infinite; }
20
+ }
21
+ @keyframes dm-aura { 50% { opacity: 0.4; } }
22
+ @media print { .aura::before { display: none; } }
23
+ }
24
+
25
+ @layer components {
26
+ .hover-3d { border-radius: var(--radius-md); }
27
+ @media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
28
+ .hover-3d { transition: transform 200ms ease; }
29
+ .hover-3d:hover:not(:focus-within) { transform: perspective(60rem) rotateX(var(--hover-3d-x, 2deg)) rotateY(var(--hover-3d-y, -2deg)); }
30
+ }
31
+ @media print { .hover-3d { transform: none; } }
32
+ }
33
+
34
+ @layer components {
35
+ .hover-gallery { display: grid; gap: 0.5rem; min-inline-size: 0; color: var(--color-on-surface); }
36
+ .hover-gallery-stage { aspect-ratio: var(--hover-gallery-ratio, 4 / 3); overflow: hidden; border-radius: var(--radius-md); }
37
+ .hover-gallery-stage img { inline-size: 100%; block-size: 100%; object-fit: cover; }
38
+ .hover-gallery-controls { display: flex; flex-wrap: wrap; gap: 0.5rem; }
39
+ .hover-gallery-controls > button { border: 1px solid currentColor; color: inherit; background: var(--color-surface-container); padding: 0.25rem; border-radius: var(--radius-sm); cursor: pointer; }
40
+ .hover-gallery-controls img { display: block; inline-size: 3rem; block-size: 3rem; object-fit: cover; }
41
+ .hover-gallery-controls > button[aria-pressed="true"] { color: var(--color-primary); outline: 2px solid currentColor; }
42
+ .hover-gallery-controls > button:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
43
+ @media (hover: hover) and (prefers-reduced-motion: no-preference) {
44
+ .hover-gallery-controls > button:hover { background: var(--color-primary-container); }
45
+ }
46
+ @media print { .hover-gallery-controls { display: none; } }
47
+ }
48
+
49
+ @layer components {
50
+ .text-rotate { display: inline-grid; color: var(--color-on-surface); vertical-align: baseline; }
51
+ .text-rotate > span { grid-area: 1 / 1; visibility: hidden; }
52
+ .text-rotate > span:first-child { visibility: visible; }
53
+ @media (prefers-reduced-motion: no-preference) {
54
+ .text-rotate-animated > span { animation: dm-text-rotate var(--text-rotate-duration, 6s) steps(1, end) infinite; }
55
+ .text-rotate-animated > span:nth-child(2) { animation-delay: calc(var(--text-rotate-duration, 6s) / -3); }
56
+ .text-rotate-animated > span:nth-child(3) { animation-delay: calc(var(--text-rotate-duration, 6s) / -3 * 2); }
57
+ .text-rotate-animated:is(:hover, :focus-within, .text-rotate-paused) > span { animation-play-state: paused; }
58
+ }
59
+ @keyframes dm-text-rotate { 0%, 33.32% { visibility: visible; } 33.33%, 100% { visibility: hidden; } }
60
+ @media print {
61
+ .text-rotate > span { animation: none; visibility: hidden; }
62
+ .text-rotate > span:first-child { visibility: visible; }
63
+ }
64
+ }
65
+
@@ -0,0 +1,16 @@
1
+ @layer components {
2
+ .text-rotate { display: inline-grid; color: var(--color-on-surface); vertical-align: baseline; }
3
+ .text-rotate > span { grid-area: 1 / 1; visibility: hidden; }
4
+ .text-rotate > span:first-child { visibility: visible; }
5
+ @media (prefers-reduced-motion: no-preference) {
6
+ .text-rotate-animated > span { animation: dm-text-rotate var(--text-rotate-duration, 6s) steps(1, end) infinite; }
7
+ .text-rotate-animated > span:nth-child(2) { animation-delay: calc(var(--text-rotate-duration, 6s) / -3); }
8
+ .text-rotate-animated > span:nth-child(3) { animation-delay: calc(var(--text-rotate-duration, 6s) / -3 * 2); }
9
+ .text-rotate-animated:is(:hover, :focus-within, .text-rotate-paused) > span { animation-play-state: paused; }
10
+ }
11
+ @keyframes dm-text-rotate { 0%, 33.32% { visibility: visible; } 33.33%, 100% { visibility: hidden; } }
12
+ @media print {
13
+ .text-rotate > span { animation: none; visibility: hidden; }
14
+ .text-rotate > span:first-child { visibility: visible; }
15
+ }
16
+ }
@@ -43,7 +43,7 @@ export const css = `/**
43
43
  background-color: transparent;
44
44
  border: none;
45
45
  cursor: pointer;
46
- text-align: left;
46
+ text-align: start;
47
47
  transition: background-color 150ms ease-in-out;
48
48
  }
49
49
 
@@ -57,7 +57,8 @@ export const css = `/**
57
57
  box-shadow: 0 0 0 3px color-mix(in oklch, currentColor 20%, transparent);
58
58
  }
59
59
 
60
- .accordion-item.open .accordion-header {
60
+ .accordion-item:not(details):is(.open, .accordion-item-open) > .accordion-header,
61
+ details.accordion-item[open] > .accordion-header {
61
62
  background-color: var(--color-surface-container);
62
63
  }
63
64
 
@@ -68,7 +69,7 @@ export const css = `/**
68
69
  justify-content: center;
69
70
  width: 1.5rem;
70
71
  height: 1.5rem;
71
- margin-right: 0.75rem;
72
+ margin-inline-end: 0.75rem;
72
73
  color: var(--color-on-surface-variant);
73
74
  flex-shrink: 0;
74
75
  }
@@ -93,13 +94,14 @@ export const css = `/**
93
94
  justify-content: center;
94
95
  width: 1.5rem;
95
96
  height: 1.5rem;
96
- margin-left: auto;
97
+ margin-inline-start: auto;
97
98
  color: var(--color-on-surface-variant);
98
99
  transition: transform 200ms ease-in-out;
99
100
  flex-shrink: 0;
100
101
  }
101
102
 
102
- .accordion-item.open .accordion-expand {
103
+ .accordion-item:not(details):is(.open, .accordion-item-open) > .accordion-header > .accordion-expand,
104
+ details.accordion-item[open] > .accordion-header > .accordion-expand {
103
105
  transform: rotate(180deg);
104
106
  }
105
107
 
@@ -110,12 +112,14 @@ export const css = `/**
110
112
  transition: grid-template-rows 200ms ease-in-out;
111
113
  }
112
114
 
113
- .accordion-item.open .accordion-content {
115
+ .accordion-item:not(details):is(.open, .accordion-item-open) > .accordion-content,
116
+ details.accordion-item[open] > .accordion-content {
114
117
  grid-template-rows: 1fr;
115
118
  }
116
119
 
117
120
  .accordion-body {
118
121
  overflow: hidden;
122
+ min-block-size: 0;
119
123
  }
120
124
 
121
125
  .accordion-body-inner {
@@ -153,7 +157,8 @@ export const css = `/**
153
157
  }
154
158
 
155
159
  .accordion-filled .accordion-header:hover,
156
- .accordion-filled .accordion-item.open .accordion-header {
160
+ .accordion-filled > .accordion-item:not(details):is(.open, .accordion-item-open) > .accordion-header,
161
+ .accordion-filled > details.accordion-item[open] > .accordion-header {
157
162
  background-color: var(--color-surface-container-high);
158
163
  }
159
164
 
@@ -225,15 +230,34 @@ export const css = `/**
225
230
  }
226
231
 
227
232
  /* Color Variants */
228
- .accordion-primary .accordion-item.open .accordion-header {
233
+ .accordion-primary > .accordion-item:not(details):is(.open, .accordion-item-open) > .accordion-header,
234
+ .accordion-primary > details.accordion-item[open] > .accordion-header {
229
235
  background-color: var(--color-primary-container);
230
236
  color: var(--color-on-primary-container);
231
237
  }
232
238
 
233
- .accordion-primary .accordion-item.open .accordion-expand {
239
+ .accordion-primary > .accordion-item:not(details):is(.open, .accordion-item-open) > .accordion-header > .accordion-expand,
240
+ .accordion-primary > details.accordion-item[open] > .accordion-header > .accordion-expand {
234
241
  color: var(--color-on-primary-container);
235
242
  }
236
243
 
244
+ .accordion-outlined { border: 1px solid var(--color-outline-variant); }
245
+ .accordion-comfortable .accordion-header { padding: 1.25rem; }
246
+ .accordion-header-icon { display: flex; align-items: center; gap: 0.75rem; }
247
+ .accordion-header-icon-leading { inline-size: 1.25rem; block-size: 1.25rem; flex: none; }
248
+ .accordion-item-disabled > .accordion-header { opacity: 0.6; cursor: not-allowed; }
249
+ .accordion-no-animation .accordion-content, .accordion-no-animation .accordion-expand { transition: none; }
250
+ .accordion-secondary > .accordion-item:not(details):is(.open, .accordion-item-open) > .accordion-header,
251
+ .accordion-secondary > details.accordion-item[open] > .accordion-header { color: var(--color-secondary); }
252
+ .accordion-tertiary > .accordion-item:not(details):is(.open, .accordion-item-open) > .accordion-header,
253
+ .accordion-tertiary > details.accordion-item[open] > .accordion-header { color: var(--color-tertiary); }
254
+ details.accordion-item > summary { list-style: none; }
255
+ details.accordion-item > summary::-webkit-details-marker { display: none; }
256
+ details.accordion-item:not([open]) > .accordion-content,
257
+ .accordion-item:not(details):not(.open):not(.accordion-item-open) > .accordion-content,
258
+ .accordion-content[hidden] { display: none; }
259
+ .accordion-title, .accordion-body-inner { min-inline-size: 0; overflow-wrap: anywhere; }
260
+
237
261
  /* Reduce Motion */
238
262
  @media (prefers-reduced-motion: reduce) {
239
263
  .accordion-content,
@@ -5,6 +5,8 @@ export const css = `/**
5
5
  */
6
6
 
7
7
  @layer components {
8
+ :where(.autocomplete, .autocomplete *) { box-sizing: border-box; }
9
+
8
10
  /* Autocomplete Container */
9
11
  .autocomplete {
10
12
  position: relative;
@@ -15,6 +17,7 @@ export const css = `/**
15
17
  /* Autocomplete Input */
16
18
  .autocomplete-input {
17
19
  width: 100%;
20
+ min-inline-size: 0;
18
21
  padding: 0.75rem 1rem;
19
22
  font-size: 0.875rem;
20
23
  line-height: 1.5;
@@ -25,6 +28,37 @@ export const css = `/**
25
28
  transition: border-color 150ms ease-in-out, box-shadow 150ms ease-in-out;
26
29
  }
27
30
 
31
+ .autocomplete-input-wrapper {
32
+ position: relative;
33
+ display: flex;
34
+ align-items: center;
35
+ }
36
+
37
+ .autocomplete-toggle {
38
+ position: absolute;
39
+ inset-inline-end: 0.125rem;
40
+ inset-block-start: 50%;
41
+ transform: translateY(-50%);
42
+ display: grid;
43
+ place-items: center;
44
+ inline-size: 2.75rem;
45
+ block-size: 2.75rem;
46
+ padding: 0;
47
+ font: inherit;
48
+ color: var(--color-on-surface);
49
+ background: transparent;
50
+ border: none;
51
+ border-radius: var(--radius-sm);
52
+ cursor: pointer;
53
+ }
54
+
55
+ .autocomplete-toggle:hover:not(:disabled) { background-color: var(--color-surface-container); }
56
+ .autocomplete-toggle:focus-visible { outline: 2px solid currentColor; outline-offset: -3px; }
57
+ .autocomplete-toggle:disabled { opacity: 0.38; cursor: not-allowed; }
58
+ .autocomplete-sm .autocomplete-toggle { inline-size: 1.75rem; block-size: 1.75rem; }
59
+ .autocomplete-outlined .autocomplete-input { background-color: transparent; }
60
+ .autocomplete-options { list-style: none; margin: 0; padding: 0.25rem; }
61
+
28
62
  .autocomplete-input:focus {
29
63
  outline: none;
30
64
  box-shadow: 0 0 0 3px color-mix(in oklch, currentColor 20%, transparent);
@@ -41,8 +75,7 @@ export const css = `/**
41
75
  .autocomplete-dropdown {
42
76
  position: absolute;
43
77
  top: 100%;
44
- left: 0;
45
- right: 0;
78
+ inset-inline: 0;
46
79
  z-index: 1000;
47
80
  max-height: 15rem;
48
81
  margin-top: 0.25rem;
@@ -58,12 +91,18 @@ export const css = `/**
58
91
  }
59
92
 
60
93
  .autocomplete.autocomplete-open .autocomplete-dropdown,
94
+ .autocomplete-dropdown.autocomplete-dropdown-open,
61
95
  .autocomplete-dropdown.show {
62
96
  opacity: 1;
63
97
  visibility: visible;
64
98
  transform: translateY(0);
65
99
  }
66
100
 
101
+ .autocomplete-dropdown[hidden],
102
+ .autocomplete-option[hidden],
103
+ .autocomplete-no-results[hidden],
104
+ .autocomplete-no-options[hidden] { display: none; }
105
+
67
106
  /* Autocomplete Options */
68
107
  .autocomplete-option {
69
108
  display: flex;
@@ -78,16 +117,20 @@ export const css = `/**
78
117
 
79
118
  .autocomplete-option:hover,
80
119
  .autocomplete-option:focus,
120
+ .autocomplete-option.autocomplete-option-focused,
81
121
  .autocomplete-option.highlighted {
82
122
  background-color: var(--color-surface-container);
83
123
  }
84
124
 
85
- .autocomplete-option.selected {
125
+ .autocomplete-option.selected,
126
+ .autocomplete-option.autocomplete-option-selected,
127
+ .autocomplete-option[aria-selected="true"] {
86
128
  background-color: var(--color-primary-container);
87
129
  color: var(--color-on-primary-container);
88
130
  }
89
131
 
90
132
  .autocomplete-option:disabled,
133
+ .autocomplete-option[aria-disabled="true"],
91
134
  .autocomplete-option.disabled {
92
135
  color: var(--color-on-surface-variant);
93
136
  cursor: not-allowed;
@@ -134,7 +177,8 @@ export const css = `/**
134
177
  }
135
178
 
136
179
  /* Group Header */
137
- .autocomplete-group-header {
180
+ .autocomplete-group-header,
181
+ .autocomplete-group-label {
138
182
  padding: 0.5rem 1rem;
139
183
  font-size: 0.75rem;
140
184
  font-weight: 600;
@@ -145,7 +189,8 @@ export const css = `/**
145
189
  }
146
190
 
147
191
  /* No Results */
148
- .autocomplete-no-results {
192
+ .autocomplete-no-results,
193
+ .autocomplete-no-options {
149
194
  padding: 1rem;
150
195
  text-align: center;
151
196
  font-size: 0.875rem;
@@ -165,7 +210,7 @@ export const css = `/**
165
210
  /* Clear Button */
166
211
  .autocomplete-clear {
167
212
  position: absolute;
168
- right: 0.75rem;
213
+ inset-inline-end: 0.75rem;
169
214
  top: 50%;
170
215
  transform: translateY(-50%);
171
216
  display: flex;
@@ -188,28 +233,31 @@ export const css = `/**
188
233
 
189
234
  /* With Clear Button */
190
235
  .autocomplete-clearable .autocomplete-input {
191
- padding-right: 2.5rem;
236
+ padding-inline-end: 2.5rem;
192
237
  }
193
238
 
194
239
  /* Multi-select Tags */
195
- .autocomplete-tags {
240
+ .autocomplete-tags,
241
+ .autocomplete-chips {
196
242
  display: flex;
197
243
  flex-wrap: wrap;
198
244
  gap: 0.25rem;
199
245
  padding: 0.375rem;
200
- padding-right: 2.5rem;
246
+ padding-inline-end: 2.5rem;
201
247
  min-height: 2.75rem;
202
248
  background-color: var(--color-surface);
203
249
  border: 1px solid var(--color-outline);
204
250
  border-radius: var(--radius-sm);
205
251
  }
206
252
 
207
- .autocomplete-tags:focus-within {
253
+ .autocomplete-tags:focus-within,
254
+ .autocomplete-chips:focus-within {
208
255
  border-color: var(--color-primary);
209
256
  box-shadow: 0 0 0 3px var(--color-primary-container);
210
257
  }
211
258
 
212
- .autocomplete-tag {
259
+ .autocomplete-tag,
260
+ .autocomplete-chip {
213
261
  display: inline-flex;
214
262
  align-items: center;
215
263
  gap: 0.25rem;
@@ -220,7 +268,8 @@ export const css = `/**
220
268
  border-radius: var(--radius-xs);
221
269
  }
222
270
 
223
- .autocomplete-tag-remove {
271
+ .autocomplete-tag-remove,
272
+ .autocomplete-chip-remove {
224
273
  display: flex;
225
274
  align-items: center;
226
275
  justify-content: center;
@@ -234,7 +283,8 @@ export const css = `/**
234
283
  transition: background-color 150ms ease-in-out;
235
284
  }
236
285
 
237
- .autocomplete-tag-remove:hover {
286
+ .autocomplete-tag-remove:hover,
287
+ .autocomplete-chip-remove:hover {
238
288
  background-color: var(--color-on-primary-container);
239
289
  color: var(--color-primary-container);
240
290
  }
@@ -342,6 +392,10 @@ export const css = `/**
342
392
  font-size: 1rem;
343
393
  }
344
394
 
395
+ /* Reserve the toggle's space after size shorthands set input padding. */
396
+ .autocomplete-input-wrapper .autocomplete-input { padding-inline-end: 3.25rem; }
397
+ .autocomplete-sm .autocomplete-input-wrapper .autocomplete-input { padding-inline-end: 2.25rem; }
398
+
345
399
  /* Reduce Motion */
346
400
  @media (prefers-reduced-motion: reduce) {
347
401
  .autocomplete-dropdown {
@@ -14,7 +14,7 @@ export const css = `/**
14
14
  width: 3rem;
15
15
  height: 3rem;
16
16
  border-radius: var(--radius-full);
17
- overflow: hidden;
17
+ overflow: visible;
18
18
  background-color: var(--color-surface-container);
19
19
  color: var(--color-on-surface);
20
20
  font-weight: 500;
@@ -25,6 +25,7 @@ export const css = `/**
25
25
  width: 100%;
26
26
  height: 100%;
27
27
  object-fit: cover;
28
+ border-radius: inherit;
28
29
  }
29
30
 
30
31
  /* Avatar Placeholder */
@@ -34,7 +35,9 @@ export const css = `/**
34
35
  justify-content: center;
35
36
  width: 100%;
36
37
  height: 100%;
37
- font-size: 1.25rem;
38
+ font-size: inherit;
39
+ border-radius: inherit;
40
+ overflow: hidden;
38
41
  text-transform: uppercase;
39
42
  }
40
43
 
@@ -136,24 +139,28 @@ export const css = `/**
136
139
  }
137
140
 
138
141
  .avatar-ring-primary {
139
- outline-color: var(--color-primary);
142
+ box-shadow: 0 0 0 3px var(--color-primary);
140
143
  }
141
144
 
142
145
  .avatar-ring-secondary {
143
- outline-color: var(--color-secondary);
146
+ box-shadow: 0 0 0 3px var(--color-secondary);
144
147
  }
145
148
 
146
149
  .avatar-ring-tertiary {
147
- outline-color: var(--color-tertiary);
150
+ box-shadow: 0 0 0 3px var(--color-tertiary);
148
151
  }
149
152
 
150
153
  /* Online/Offline Indicator */
151
154
  .avatar-online::after,
152
- .avatar-offline::after {
155
+ .avatar-offline::after,
156
+ .avatar-status-online::after,
157
+ .avatar-status-offline::after,
158
+ .avatar-status-busy::after,
159
+ .avatar-status-away::after {
153
160
  content: '';
154
161
  position: absolute;
155
- bottom: 0;
156
- right: 0;
162
+ inset-block-end: 0;
163
+ inset-inline-end: 0;
157
164
  width: 25%;
158
165
  height: 25%;
159
166
  min-width: 0.5rem;
@@ -162,14 +169,19 @@ export const css = `/**
162
169
  border: 2px solid var(--color-surface);
163
170
  }
164
171
 
165
- .avatar-online::after {
172
+ .avatar-online::after,
173
+ .avatar-status-online::after {
166
174
  background-color: var(--color-success);
167
175
  }
168
176
 
169
- .avatar-offline::after {
177
+ .avatar-offline::after,
178
+ .avatar-status-offline::after {
170
179
  background-color: var(--color-outline);
171
180
  }
172
181
 
182
+ .avatar-status-busy::after { background-color: var(--color-error); }
183
+ .avatar-status-away::after { background-color: var(--color-warning); }
184
+
173
185
  /* Avatar Group */
174
186
  .avatar-group {
175
187
  display: flex;
@@ -179,21 +191,33 @@ export const css = `/**
179
191
 
180
192
  .avatar-group .avatar {
181
193
  border: 2px solid var(--color-surface);
182
- margin-left: -0.75rem;
194
+ margin-inline-start: -0.75rem;
183
195
  }
184
196
 
185
197
  .avatar-group .avatar:last-child {
186
- margin-left: 0;
198
+ margin-inline-start: 0;
187
199
  }
188
200
 
189
201
  /* Avatar Group Sizes */
190
202
  .avatar-group-sm .avatar {
191
- margin-left: -0.5rem;
203
+ margin-inline-start: -0.5rem;
192
204
  }
193
205
 
194
206
  .avatar-group-lg .avatar {
195
- margin-left: -1rem;
196
- }
207
+ margin-inline-start: -1rem;
208
+ }
209
+
210
+ /* Historical documented composition classes. */
211
+ .avatar-image { inline-size: 100%; block-size: 100%; border-radius: inherit; overflow: hidden; }
212
+ .avatar-icon { display: inline-flex; align-items: center; justify-content: center; inline-size: 100%; block-size: 100%; }
213
+ .avatar-circle { border-radius: var(--radius-full); }
214
+ .avatar-bordered { border: 2px solid currentColor; }
215
+ .avatar-clickable { cursor: pointer; }
216
+ .avatar-overflow { font-size: 0.875rem; }
217
+ .avatar-group-dense > .avatar { margin-inline-start: -1rem; }
218
+ .avatar-group-xs > .avatar { inline-size: 1.5rem; block-size: 1.5rem; font-size: 0.625rem; }
219
+ .avatar-group-xl > .avatar { inline-size: 6rem; block-size: 6rem; font-size: 2rem; }
220
+ .avatar-group-dense > .avatar:last-child { margin-inline-start: 0; }
197
221
 
198
222
  /* Focus State for Interactive Avatars */
199
223
  .avatar:focus-visible {
@@ -7,6 +7,7 @@ export const css = `/**
7
7
  @layer components {
8
8
  /* Base Badge */
9
9
  .badge {
10
+ box-sizing: border-box;
10
11
  display: inline-flex;
11
12
  align-items: center;
12
13
  justify-content: center;
@@ -14,7 +15,10 @@ export const css = `/**
14
15
  font-size: 0.75rem;
15
16
  font-weight: 500;
16
17
  line-height: 1rem;
17
- white-space: nowrap;
18
+ white-space: normal;
19
+ max-inline-size: 100%;
20
+ overflow-wrap: anywhere;
21
+ min-inline-size: 0;
18
22
  border-radius: var(--radius-full);
19
23
  background-color: var(--color-surface-container);
20
24
  color: var(--color-on-surface);
@@ -228,13 +232,13 @@ export const css = `/**
228
232
  /* Badge with Indicator Dot */
229
233
  .badge-indicator {
230
234
  position: relative;
231
- padding-left: 1rem;
235
+ padding-inline-start: 1rem;
232
236
  }
233
237
 
234
238
  .badge-indicator::before {
235
239
  content: '';
236
240
  position: absolute;
237
- left: 0.375rem;
241
+ inset-inline-start: 0.375rem;
238
242
  top: 50%;
239
243
  transform: translateY(-50%);
240
244
  width: 0.375rem;
@@ -243,6 +247,14 @@ export const css = `/**
243
247
  background-color: currentColor;
244
248
  }
245
249
 
250
+ .badge-filled { font-weight: 500; }
251
+ .badge-md { padding: 0.125rem 0.5rem; font-size: 0.75rem; line-height: 1rem; }
252
+ .badge-notification { position: absolute; inset-block-start: 0; inset-inline-end: 0; transform: translate(50%, -50%); }
253
+ .badge-notification:dir(rtl) { transform: translate(-50%, -50%); }
254
+ .badge-removable { gap: 0.25rem; }
255
+ .badge-removable > button { display: inline-flex; padding: 0; border: 0; color: inherit; background: transparent; cursor: pointer; }
256
+ .badge-removable > button:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
257
+
246
258
  /* Empty Badge (just a dot) */
247
259
  .badge-dot {
248
260
  width: 0.5rem;