@adamarant/designsystem 0.11.2

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 (84) hide show
  1. package/README.md +101 -0
  2. package/dist/designsystem.css +13494 -0
  3. package/dist/designsystem.js +67 -0
  4. package/dist/designsystem.min.css +2 -0
  5. package/package.json +111 -0
  6. package/src/base/index.css +2 -0
  7. package/src/base/reset.css +119 -0
  8. package/src/base/typography.css +172 -0
  9. package/src/components/accordion.css +166 -0
  10. package/src/components/admin-layout.css +371 -0
  11. package/src/components/alert.css +159 -0
  12. package/src/components/avatar.css +109 -0
  13. package/src/components/badge.css +80 -0
  14. package/src/components/bottom-nav.css +125 -0
  15. package/src/components/bottom-sheet.css +146 -0
  16. package/src/components/breadcrumb.css +102 -0
  17. package/src/components/button.css +250 -0
  18. package/src/components/card.css +117 -0
  19. package/src/components/chip.css +79 -0
  20. package/src/components/collapsible.css +112 -0
  21. package/src/components/color-picker.css +82 -0
  22. package/src/components/combobox.css +420 -0
  23. package/src/components/command.css +210 -0
  24. package/src/components/context-menu.css +162 -0
  25. package/src/components/copy-button.css +106 -0
  26. package/src/components/custom-select.css +446 -0
  27. package/src/components/datepicker.css +301 -0
  28. package/src/components/description-list.css +100 -0
  29. package/src/components/divider.css +66 -0
  30. package/src/components/drawer.css +234 -0
  31. package/src/components/drop-zone.css +166 -0
  32. package/src/components/dropdown.css +169 -0
  33. package/src/components/empty-state.css +75 -0
  34. package/src/components/field.css +112 -0
  35. package/src/components/gallery.css +257 -0
  36. package/src/components/hero.css +111 -0
  37. package/src/components/icon-btn.css +103 -0
  38. package/src/components/index.css +74 -0
  39. package/src/components/input.css +311 -0
  40. package/src/components/kbd.css +54 -0
  41. package/src/components/media-library.css +230 -0
  42. package/src/components/modal.css +136 -0
  43. package/src/components/nav.css +198 -0
  44. package/src/components/number-input.css +163 -0
  45. package/src/components/pagination.css +175 -0
  46. package/src/components/pin-input.css +136 -0
  47. package/src/components/popover.css +111 -0
  48. package/src/components/progress.css +217 -0
  49. package/src/components/prose.css +337 -0
  50. package/src/components/result.css +80 -0
  51. package/src/components/scroll-area.css +73 -0
  52. package/src/components/search.css +311 -0
  53. package/src/components/segmented-control.css +94 -0
  54. package/src/components/skeleton.css +100 -0
  55. package/src/components/slider.css +133 -0
  56. package/src/components/sortable.css +70 -0
  57. package/src/components/spinner.css +60 -0
  58. package/src/components/star-rating.css +121 -0
  59. package/src/components/stat-card.css +44 -0
  60. package/src/components/table.css +359 -0
  61. package/src/components/tabs.css +215 -0
  62. package/src/components/tag.css +188 -0
  63. package/src/components/timeline.css +130 -0
  64. package/src/components/toast.css +90 -0
  65. package/src/components/toggle.css +173 -0
  66. package/src/components/toolbar.css +206 -0
  67. package/src/components/tooltip.css +167 -0
  68. package/src/components/truncated-text.css +75 -0
  69. package/src/index.css +21 -0
  70. package/src/js/theme.js +67 -0
  71. package/src/tokens/colors.css +256 -0
  72. package/src/tokens/index.css +11 -0
  73. package/src/tokens/shadows.css +55 -0
  74. package/src/tokens/spacing.css +82 -0
  75. package/src/tokens/tokens.json +413 -0
  76. package/src/tokens/typography.css +90 -0
  77. package/src/utilities/a11y.css +102 -0
  78. package/src/utilities/index.css +7 -0
  79. package/src/utilities/interactive.css +121 -0
  80. package/src/utilities/layout.css +273 -0
  81. package/src/utilities/sizing.css +85 -0
  82. package/src/utilities/spacing.css +204 -0
  83. package/src/utilities/states.css +182 -0
  84. package/src/utilities/text.css +381 -0
@@ -0,0 +1,371 @@
1
+ /* ==========================================================================
2
+ Component: Admin Layout
3
+ Parent-driven sidebar + header + main content system for admin dashboards.
4
+
5
+ All width/offset decisions are controlled by a SINGLE class on .ds-admin:
6
+ - .ds-admin--expanded → sidebar 16rem, offsets 16rem
7
+ - .ds-admin--collapsed → sidebar 4rem, offsets 4rem
8
+
9
+ This guarantees sidebar, header, and main content transition in perfect sync.
10
+
11
+ Variants:
12
+ ds-admin--expanded Sidebar open (16rem) — default on desktop
13
+ ds-admin--collapsed Sidebar collapsed (4rem) — icons only
14
+
15
+ Usage:
16
+ <div class="ds-admin ds-admin--expanded">
17
+ <aside class="ds-admin__sidebar">
18
+ <div class="ds-admin__sidebar-header">Logo</div>
19
+ <nav class="ds-admin__nav">
20
+ <a class="ds-admin__nav-item ds-admin__nav-item--active">
21
+ <span class="ds-admin__nav-icon">...</span>
22
+ <span class="ds-admin__nav-label">Dashboard</span>
23
+ </a>
24
+ <div class="ds-admin__subnav">
25
+ <a class="ds-admin__subnav-item">Sub page</a>
26
+ </div>
27
+ </nav>
28
+ <div class="ds-admin__sidebar-footer">
29
+ <a class="ds-admin__footer-link">Settings</a>
30
+ </div>
31
+ </aside>
32
+ <header class="ds-admin__header">
33
+ <div class="ds-admin__header-inner">...</div>
34
+ </header>
35
+ <main class="ds-admin__main">
36
+ <div class="ds-admin__content">...</div>
37
+ </main>
38
+ </div>
39
+
40
+ Mobile: Sidebar is hidden. Use ds-drawer for mobile menu.
41
+ Toggle .ds-admin__overlay when mobile menu is open.
42
+
43
+ ARIA:
44
+ - <aside> should have role="navigation" or aria-label="Admin navigation"
45
+ - Active nav item: aria-current="page"
46
+ - Mobile toggle: aria-expanded, aria-controls
47
+ ========================================================================== */
48
+
49
+ /* --- Layout Variables --- */
50
+ .ds-admin {
51
+ --ds-admin-sidebar-w: 16rem;
52
+ --ds-admin-sidebar-w-collapsed: 4rem;
53
+ --ds-admin-header-h: var(--ds-size-4);
54
+ }
55
+
56
+ /* ==========================================================================
57
+ Sidebar
58
+ ========================================================================== */
59
+
60
+ .ds-admin__sidebar {
61
+ display: none;
62
+ position: fixed;
63
+ inset-block-start: 0;
64
+ inset-inline-start: 0;
65
+ z-index: var(--ds-z-dropdown);
66
+ height: 100dvh;
67
+ flex-direction: column;
68
+ border-inline-end: 1px solid var(--ds-color-border);
69
+ background-color: var(--ds-color-surface);
70
+ transition: width var(--ds-duration-normal) var(--ds-ease-default);
71
+ overflow: hidden;
72
+ }
73
+
74
+ @media (min-width: 1024px) {
75
+ .ds-admin__sidebar {
76
+ display: flex;
77
+ }
78
+
79
+ .ds-admin--expanded .ds-admin__sidebar {
80
+ width: var(--ds-admin-sidebar-w);
81
+ }
82
+
83
+ .ds-admin--collapsed .ds-admin__sidebar {
84
+ width: var(--ds-admin-sidebar-w-collapsed);
85
+ }
86
+
87
+ /* Centered items in collapsed state */
88
+ .ds-admin--collapsed .ds-admin__nav-item {
89
+ justify-content: center;
90
+ }
91
+
92
+ .ds-admin--collapsed .ds-admin__footer-link {
93
+ justify-content: center;
94
+ }
95
+
96
+ /* Hide labels in collapsed state */
97
+ .ds-admin--collapsed .ds-admin__nav-label,
98
+ .ds-admin--collapsed .ds-admin__sidebar-badge {
99
+ display: none;
100
+ }
101
+
102
+ /* Hide subnav in collapsed state */
103
+ .ds-admin--collapsed .ds-admin__subnav {
104
+ display: none;
105
+ }
106
+ }
107
+
108
+ /* --- Sidebar Header (logo area) --- */
109
+ .ds-admin__sidebar-header {
110
+ display: flex;
111
+ height: var(--ds-admin-header-h);
112
+ align-items: center;
113
+ gap: var(--ds-space-2);
114
+ border-block-end: 1px solid var(--ds-color-border);
115
+ padding-inline: var(--ds-space-4);
116
+ flex-shrink: 0;
117
+ }
118
+
119
+ .ds-admin--collapsed .ds-admin__sidebar-header {
120
+ justify-content: center;
121
+ }
122
+
123
+ /* --- Sidebar Badge (env indicator, version, etc.) --- */
124
+ .ds-admin__sidebar-badge {
125
+ border-radius: var(--ds-radius-md);
126
+ border: 1px solid var(--ds-color-border);
127
+ background-color: var(--ds-color-surface-muted);
128
+ padding: var(--ds-space-0-5) var(--ds-space-1-5);
129
+ font-size: var(--ds-text-xs);
130
+ font-weight: var(--ds-weight-medium);
131
+ color: var(--ds-color-text-secondary);
132
+ }
133
+
134
+ /* --- Navigation Area --- */
135
+ .ds-admin__nav {
136
+ flex: 1;
137
+ overflow-y: auto;
138
+ padding: var(--ds-space-6) var(--ds-space-3);
139
+ }
140
+
141
+ .ds-admin__nav > * + * {
142
+ margin-block-start: var(--ds-space-1);
143
+ }
144
+
145
+ /* --- Nav Item --- */
146
+ .ds-admin__nav-item {
147
+ display: flex;
148
+ align-items: center;
149
+ gap: var(--ds-space-3);
150
+ border-radius: var(--ds-radius-xl);
151
+ padding: var(--ds-space-2-5) var(--ds-space-3);
152
+ color: var(--ds-color-text-secondary);
153
+ transition:
154
+ background-color var(--ds-duration-fast) var(--ds-ease-default),
155
+ color var(--ds-duration-fast) var(--ds-ease-default);
156
+ }
157
+
158
+ .ds-admin__nav-item:hover {
159
+ background-color: var(--ds-color-surface-hover);
160
+ color: var(--ds-color-text);
161
+ }
162
+
163
+ .ds-admin__nav-item--active,
164
+ .ds-admin__nav-item--active:hover {
165
+ background-color: var(--ds-color-surface-elevated);
166
+ color: var(--ds-color-text);
167
+ }
168
+
169
+ /* --- Nav Icon (fixed size prevents reflow on collapse) --- */
170
+ .ds-admin__nav-icon {
171
+ display: flex;
172
+ align-items: center;
173
+ justify-content: center;
174
+ width: 20px;
175
+ height: 20px;
176
+ flex-shrink: 0;
177
+ }
178
+
179
+ /* --- Nav Label --- */
180
+ .ds-admin__nav-label {
181
+ white-space: nowrap;
182
+ font-size: var(--ds-text-sm);
183
+ font-weight: var(--ds-weight-medium);
184
+ }
185
+
186
+ /* --- Sub-Navigation (nested under a parent item) --- */
187
+ .ds-admin__subnav {
188
+ display: flex;
189
+ flex-direction: column;
190
+ gap: var(--ds-space-0-5);
191
+ margin-inline-start: 1.75rem;
192
+ padding-inline-start: var(--ds-space-3);
193
+ padding-block: var(--ds-space-1);
194
+ border-inline-start: 1px solid var(--ds-color-border);
195
+ }
196
+
197
+ .ds-admin__subnav-item {
198
+ display: block;
199
+ padding: var(--ds-space-1-5) var(--ds-space-3);
200
+ font-size: var(--ds-text-sm);
201
+ font-weight: var(--ds-weight-medium);
202
+ color: var(--ds-color-text-tertiary);
203
+ border-radius: var(--ds-radius-lg);
204
+ transition:
205
+ background-color var(--ds-duration-fast) var(--ds-ease-default),
206
+ color var(--ds-duration-fast) var(--ds-ease-default);
207
+ }
208
+
209
+ .ds-admin__subnav-item:hover:not(.ds-admin__subnav-item--active) {
210
+ background-color: var(--ds-color-surface-hover);
211
+ color: var(--ds-color-text-secondary);
212
+ }
213
+
214
+ .ds-admin__subnav-item--active {
215
+ background-color: var(--ds-color-surface-elevated);
216
+ color: var(--ds-color-text);
217
+ }
218
+
219
+ /* --- Sidebar Footer --- */
220
+ .ds-admin__sidebar-footer {
221
+ border-block-start: 1px solid var(--ds-color-border);
222
+ padding: var(--ds-space-3);
223
+ }
224
+
225
+ .ds-admin__sidebar-footer > * + * {
226
+ margin-block-start: var(--ds-space-1);
227
+ }
228
+
229
+ /* --- Footer Link --- */
230
+ .ds-admin__footer-link {
231
+ display: flex;
232
+ width: 100%;
233
+ align-items: center;
234
+ gap: var(--ds-space-3);
235
+ border-radius: var(--ds-radius-xl);
236
+ padding: var(--ds-space-2-5) var(--ds-space-3);
237
+ color: var(--ds-color-text-secondary);
238
+ transition:
239
+ background-color var(--ds-duration-fast) var(--ds-ease-default),
240
+ color var(--ds-duration-fast) var(--ds-ease-default);
241
+ }
242
+
243
+ .ds-admin__footer-link:hover {
244
+ background-color: var(--ds-color-surface-hover);
245
+ color: var(--ds-color-text);
246
+ }
247
+
248
+ /* ==========================================================================
249
+ Header
250
+ ========================================================================== */
251
+
252
+ .ds-admin__header {
253
+ position: fixed;
254
+ inset-inline: 0;
255
+ inset-block-start: 0;
256
+ z-index: 40;
257
+ height: var(--ds-admin-header-h);
258
+ border-block-end: 1px solid var(--ds-color-border);
259
+ background-color: var(--ds-color-nav-bg);
260
+ backdrop-filter: blur(20px) saturate(1.5);
261
+ -webkit-backdrop-filter: blur(20px) saturate(1.5);
262
+ }
263
+
264
+ .ds-admin__header-inner {
265
+ display: flex;
266
+ height: 100%;
267
+ align-items: center;
268
+ justify-content: space-between;
269
+ padding-inline: var(--ds-space-6);
270
+ margin-inline-start: 0;
271
+ transition: margin-inline-start var(--ds-duration-normal) var(--ds-ease-default);
272
+ }
273
+
274
+ /* Hide toggle on desktop */
275
+ @media (min-width: 1024px) {
276
+ .ds-admin__header-toggle {
277
+ display: none;
278
+ }
279
+
280
+ .ds-admin--expanded .ds-admin__header-inner {
281
+ margin-inline-start: var(--ds-admin-sidebar-w);
282
+ }
283
+
284
+ .ds-admin--collapsed .ds-admin__header-inner {
285
+ margin-inline-start: var(--ds-admin-sidebar-w-collapsed);
286
+ }
287
+ }
288
+
289
+ /* ==========================================================================
290
+ Main Content
291
+ ========================================================================== */
292
+
293
+ .ds-admin__main {
294
+ padding-block-start: var(--ds-admin-header-h);
295
+ margin-inline-start: 0;
296
+ transition: margin-inline-start var(--ds-duration-normal) var(--ds-ease-default);
297
+ }
298
+
299
+ @media (min-width: 1024px) {
300
+ .ds-admin--expanded .ds-admin__main {
301
+ margin-inline-start: var(--ds-admin-sidebar-w);
302
+ }
303
+
304
+ .ds-admin--collapsed .ds-admin__main {
305
+ margin-inline-start: var(--ds-admin-sidebar-w-collapsed);
306
+ }
307
+ }
308
+
309
+ .ds-admin__content {
310
+ min-height: 100dvh;
311
+ padding: var(--ds-space-8) var(--ds-space-6);
312
+ }
313
+
314
+ @media (min-width: 768px) {
315
+ .ds-admin__content {
316
+ padding-inline: var(--ds-space-8);
317
+ }
318
+ }
319
+
320
+ @media (min-width: 1024px) {
321
+ .ds-admin__content {
322
+ padding-inline: var(--ds-space-12);
323
+ }
324
+ }
325
+
326
+ .ds-admin__container {
327
+ max-width: 80rem;
328
+ margin-inline: auto;
329
+ }
330
+
331
+ /* ==========================================================================
332
+ Mobile Overlay
333
+ ========================================================================== */
334
+
335
+ .ds-admin__overlay {
336
+ position: fixed;
337
+ inset: 0;
338
+ z-index: var(--ds-z-overlay);
339
+ background-color: var(--ds-color-overlay);
340
+ }
341
+
342
+ @media (min-width: 1024px) {
343
+ .ds-admin__overlay {
344
+ display: none;
345
+ }
346
+ }
347
+
348
+ /* ==========================================================================
349
+ Mobile Menu (fullscreen drawer, no animation — uses ds-drawer)
350
+ ========================================================================== */
351
+
352
+ .ds-admin__mobile-menu {
353
+ transition: none;
354
+ }
355
+
356
+ .ds-admin__mobile-menu .ds-drawer__content {
357
+ width: 100vw;
358
+ max-width: 100vw;
359
+ transition: none;
360
+ }
361
+
362
+ .ds-admin__mobile-menu .ds-drawer__body {
363
+ display: flex;
364
+ flex-direction: column;
365
+ }
366
+
367
+ @media (min-width: 1024px) {
368
+ .ds-admin__mobile-menu {
369
+ display: none !important;
370
+ }
371
+ }
@@ -0,0 +1,159 @@
1
+ /* ==========================================================================
2
+ Component: Alert
3
+ Contextual feedback banners with semantic variants and dismissibility.
4
+
5
+ ARIA requirements (consumer responsibility):
6
+ - Container: role="alert" (for important messages) or role="status"
7
+ - Dismissible: close button needs aria-label="Dismiss"
8
+ - For non-urgent info, use role="status" instead of role="alert"
9
+ ========================================================================== */
10
+
11
+ .ds-alert {
12
+ display: flex;
13
+ flex-direction: row;
14
+ align-items: center;
15
+ gap: var(--ds-space-3);
16
+ padding: var(--ds-space-4);
17
+ border: 1px solid var(--ds-color-border);
18
+ border-radius: var(--ds-radius-lg);
19
+ background-color: var(--ds-color-surface);
20
+ border-inline-start: var(--ds-accent-border-width) solid var(--ds-color-border);
21
+
22
+ /* --- Semantic Variants --- */
23
+
24
+ &--info {
25
+ background-color: var(--ds-color-info-subtle);
26
+ border-color: var(--ds-color-info-border);
27
+ border-inline-start-color: var(--ds-color-info);
28
+
29
+ & .ds-alert__icon { color: var(--ds-color-info); }
30
+ }
31
+
32
+ &--success {
33
+ background-color: var(--ds-color-success-subtle);
34
+ border-color: var(--ds-color-success-border);
35
+ border-inline-start-color: var(--ds-color-success);
36
+
37
+ & .ds-alert__icon { color: var(--ds-color-success); }
38
+ }
39
+
40
+ &--warning {
41
+ background-color: var(--ds-color-warning-subtle);
42
+ border-color: var(--ds-color-warning-border);
43
+ border-inline-start-color: var(--ds-color-warning);
44
+
45
+ & .ds-alert__icon { color: var(--ds-color-warning); }
46
+ }
47
+
48
+ &--error {
49
+ background-color: var(--ds-color-error-subtle);
50
+ border-color: var(--ds-color-error-border);
51
+ border-inline-start-color: var(--ds-color-error);
52
+
53
+ & .ds-alert__icon { color: var(--ds-color-error); }
54
+ }
55
+
56
+ /* --- Icon --- */
57
+
58
+ &__icon {
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ flex-shrink: 0;
63
+ width: 1.25rem;
64
+ height: 1.25rem;
65
+ color: var(--ds-color-text-secondary);
66
+ }
67
+
68
+ /* --- Content --- */
69
+
70
+ &__content {
71
+ flex: 1;
72
+ min-width: 0;
73
+ }
74
+
75
+ &__title {
76
+ font-family: var(--ds-font-sans);
77
+ font-size: var(--ds-text-sm);
78
+ font-weight: var(--ds-weight-medium);
79
+ line-height: var(--ds-leading-snug);
80
+ color: var(--ds-color-text);
81
+ }
82
+
83
+ &__description {
84
+ font-size: var(--ds-text-sm);
85
+ line-height: var(--ds-leading-normal);
86
+ color: var(--ds-color-text-secondary);
87
+ margin-block-start: var(--ds-space-1);
88
+ }
89
+
90
+ &__title + &__description {
91
+ margin-block-start: var(--ds-space-1);
92
+ }
93
+
94
+ /* --- Close Button --- */
95
+
96
+ &__close {
97
+ display: flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ flex-shrink: 0;
101
+ width: 1.5rem;
102
+ height: 1.5rem;
103
+ padding: 0;
104
+ border: none;
105
+ background: none;
106
+ color: var(--ds-color-text-tertiary);
107
+ border-radius: var(--ds-radius-sm);
108
+ cursor: pointer;
109
+ transition: color var(--ds-duration-fast) var(--ds-ease-default);
110
+
111
+ &:hover {
112
+ color: var(--ds-color-text);
113
+ }
114
+
115
+ &:focus-visible {
116
+ outline: none;
117
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
118
+ scroll-margin-block: var(--ds-space-16, 4rem);
119
+ }
120
+ }
121
+
122
+ /* --- Compact Variant --- */
123
+
124
+ &--compact {
125
+ padding: var(--ds-space-2) var(--ds-space-3);
126
+ border-radius: var(--ds-radius-none);
127
+ }
128
+
129
+ /* --- Banner Variant --- */
130
+
131
+ &--banner {
132
+ border-radius: var(--ds-radius-none);
133
+ border-inline-start: none;
134
+ border-inline-end: none;
135
+ border-block-start: 1px solid var(--ds-color-border);
136
+ border-block-end: 1px solid var(--ds-color-border);
137
+ width: 100%;
138
+
139
+ &.ds-alert--info {
140
+ border-block-start-color: var(--ds-color-info-border);
141
+ border-block-end-color: var(--ds-color-info-border);
142
+ }
143
+
144
+ &.ds-alert--success {
145
+ border-block-start-color: var(--ds-color-success-border);
146
+ border-block-end-color: var(--ds-color-success-border);
147
+ }
148
+
149
+ &.ds-alert--warning {
150
+ border-block-start-color: var(--ds-color-warning-border);
151
+ border-block-end-color: var(--ds-color-warning-border);
152
+ }
153
+
154
+ &.ds-alert--error {
155
+ border-block-start-color: var(--ds-color-error-border);
156
+ border-block-end-color: var(--ds-color-error-border);
157
+ }
158
+ }
159
+ }
@@ -0,0 +1,109 @@
1
+ /* ==========================================================================
2
+ Component: Avatar
3
+ User photos, token images, initials. Stackable in groups.
4
+ ========================================================================== */
5
+
6
+ .ds-avatar {
7
+ display: inline-flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ width: var(--ds-size-3);
11
+ height: var(--ds-size-3);
12
+ border-radius: var(--ds-radius-full);
13
+ background-color: var(--ds-color-surface-muted);
14
+ color: var(--ds-color-text-secondary);
15
+ font-family: var(--ds-font-sans);
16
+ font-size: var(--ds-text-sm);
17
+ font-weight: var(--ds-weight-medium);
18
+ line-height: var(--ds-leading-none);
19
+ overflow: hidden;
20
+ flex-shrink: 0;
21
+ position: relative;
22
+
23
+ & img {
24
+ width: 100%;
25
+ height: 100%;
26
+ object-fit: cover;
27
+ }
28
+
29
+ /* --- Sizes --- */
30
+
31
+ &--xs {
32
+ width: var(--ds-size-1);
33
+ height: var(--ds-size-1);
34
+ font-size: var(--ds-text-xs);
35
+ }
36
+
37
+ &--sm {
38
+ width: var(--ds-size-2);
39
+ height: var(--ds-size-2);
40
+ font-size: var(--ds-text-xs);
41
+ }
42
+
43
+ &--md {
44
+ width: var(--ds-size-3);
45
+ height: var(--ds-size-3);
46
+ font-size: var(--ds-text-sm);
47
+ }
48
+
49
+ &--lg {
50
+ width: var(--ds-size-4);
51
+ height: var(--ds-size-4);
52
+ font-size: var(--ds-text-base);
53
+ }
54
+
55
+ &--xl {
56
+ width: var(--ds-space-16);
57
+ height: var(--ds-space-16);
58
+ font-size: var(--ds-text-lg);
59
+ }
60
+
61
+ /* --- Shape variants --- */
62
+
63
+ &--square {
64
+ border-radius: var(--ds-radius-lg);
65
+ }
66
+
67
+ &--bordered {
68
+ border: 2px solid var(--ds-color-surface);
69
+ }
70
+
71
+ /* --- Status indicator --- */
72
+
73
+ &__status {
74
+ position: absolute;
75
+ inset-block-end: 0;
76
+ inset-inline-end: 0;
77
+ width: 0.625rem;
78
+ height: 0.625rem;
79
+ border-radius: var(--ds-radius-full);
80
+ border: 2px solid var(--ds-color-surface);
81
+
82
+ &--online {
83
+ background-color: var(--ds-color-success);
84
+ }
85
+
86
+ &--offline {
87
+ background-color: var(--ds-color-text-tertiary);
88
+ }
89
+
90
+ &--busy {
91
+ background-color: var(--ds-color-error);
92
+ }
93
+ }
94
+ }
95
+
96
+ /* --- Avatar Group --- */
97
+
98
+ .ds-avatar-group {
99
+ display: flex;
100
+ align-items: center;
101
+
102
+ & > .ds-avatar + .ds-avatar {
103
+ margin-inline-start: -0.5rem;
104
+ }
105
+
106
+ &--sm > .ds-avatar + .ds-avatar {
107
+ margin-inline-start: -0.375rem;
108
+ }
109
+ }
@@ -0,0 +1,80 @@
1
+ /* ==========================================================================
2
+ Component: Badge
3
+ Pill shape, border + subtle bg, clean and refined.
4
+ ========================================================================== */
5
+
6
+ .ds-badge {
7
+ display: inline-flex;
8
+ align-items: center;
9
+ gap: var(--ds-space-1);
10
+ padding: var(--ds-space-0-5) var(--ds-space-2-5);
11
+ font-size: var(--ds-text-xs);
12
+ font-weight: var(--ds-weight-medium);
13
+ line-height: var(--ds-leading-snug);
14
+ border-radius: var(--ds-radius-full);
15
+ white-space: nowrap;
16
+ border: 1px solid var(--ds-color-border);
17
+ background-color: var(--ds-color-surface-muted);
18
+ color: var(--ds-color-text-secondary);
19
+
20
+ /* Semantic variants — subtle bg + bright text + subtle border */
21
+ &--primary {
22
+ background-color: var(--ds-color-info-subtle);
23
+ color: var(--ds-color-info);
24
+ border-color: var(--ds-color-info-border);
25
+ }
26
+
27
+ &--success {
28
+ background-color: var(--ds-color-success-subtle);
29
+ color: var(--ds-color-success);
30
+ border-color: var(--ds-color-success-border);
31
+ }
32
+
33
+ &--warning {
34
+ background-color: var(--ds-color-warning-subtle);
35
+ color: var(--ds-color-warning);
36
+ border-color: var(--ds-color-warning-border);
37
+ }
38
+
39
+ &--error {
40
+ background-color: var(--ds-color-error-subtle);
41
+ color: var(--ds-color-error);
42
+ border-color: var(--ds-color-error-border);
43
+ }
44
+
45
+ &--info {
46
+ background-color: var(--ds-color-accent-blue-subtle);
47
+ color: var(--ds-color-accent-blue);
48
+ border-color: var(--ds-color-accent-blue-border);
49
+ }
50
+
51
+ &--purple {
52
+ background-color: var(--ds-color-accent-purple-subtle);
53
+ color: var(--ds-color-accent-purple);
54
+ border-color: var(--ds-color-accent-purple-border);
55
+ }
56
+
57
+ /* Outline (no bg) */
58
+ &--outline {
59
+ background-color: transparent;
60
+ border-color: var(--ds-color-border);
61
+ color: var(--ds-color-text-secondary);
62
+ }
63
+
64
+ /* Dot indicator */
65
+ &--dot::before {
66
+ content: '';
67
+ width: var(--ds-dot-size);
68
+ height: var(--ds-dot-size);
69
+ border-radius: var(--ds-radius-full);
70
+ background-color: currentColor;
71
+ }
72
+
73
+ /* Uppercase badge (like "NEW", "BETA") */
74
+ &--upper {
75
+ text-transform: uppercase;
76
+ font-size: var(--ds-text-2xs);
77
+ font-weight: var(--ds-weight-semibold);
78
+ letter-spacing: var(--ds-tracking-wide);
79
+ }
80
+ }