ds-tis 1.0.0-beta.10

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 (79) hide show
  1. package/LICENSE +49 -0
  2. package/README.md +125 -0
  3. package/css/base/forced-colors.css +62 -0
  4. package/css/base/icons.css +73 -0
  5. package/css/base/index.css +4 -0
  6. package/css/base/reset.css +80 -0
  7. package/css/base/typography.css +211 -0
  8. package/css/components/accordion.css +153 -0
  9. package/css/components/alert.css +161 -0
  10. package/css/components/avatar.css +76 -0
  11. package/css/components/badge.css +83 -0
  12. package/css/components/breadcrumb.css +58 -0
  13. package/css/components/button.css +364 -0
  14. package/css/components/card.css +159 -0
  15. package/css/components/checkbox.css +296 -0
  16. package/css/components/combobox.css +330 -0
  17. package/css/components/divider.css +20 -0
  18. package/css/components/form-field.css +137 -0
  19. package/css/components/index.css +28 -0
  20. package/css/components/input.css +356 -0
  21. package/css/components/link.css +67 -0
  22. package/css/components/menu.css +246 -0
  23. package/css/components/modal.css +236 -0
  24. package/css/components/pagination.css +132 -0
  25. package/css/components/radio.css +280 -0
  26. package/css/components/select.css +399 -0
  27. package/css/components/skeleton.css +52 -0
  28. package/css/components/spinner.css +59 -0
  29. package/css/components/tabs.css +79 -0
  30. package/css/components/textarea.css +218 -0
  31. package/css/components/toggle.css +202 -0
  32. package/css/components/tooltip.css +116 -0
  33. package/css/design-system.css +13 -0
  34. package/css/tokens/generated/component.css +720 -0
  35. package/css/tokens/generated/foundation.css +282 -0
  36. package/css/tokens/generated/index.css +5 -0
  37. package/css/tokens/generated/theme-dark.css +243 -0
  38. package/css/tokens/generated/theme-light.css +244 -0
  39. package/css/tokens/index.css +6 -0
  40. package/css/utilities/elevation.css +24 -0
  41. package/css/utilities/index.css +2 -0
  42. package/css/utilities/layout.css +132 -0
  43. package/docs/agent-consumer-usage.en.md +322 -0
  44. package/docs/agent-consumer-usage.md +294 -0
  45. package/docs/api/adrs.json +186 -0
  46. package/docs/api/components.json +2071 -0
  47. package/docs/api/consumer-context.json +66 -0
  48. package/docs/api/foundations.json +94 -0
  49. package/docs/api/tokens.json +6839 -0
  50. package/docs/llms-full.txt +23699 -0
  51. package/docs/llms.txt +109 -0
  52. package/docs/templates/contact.html +364 -0
  53. package/docs/templates/dashboard.html +318 -0
  54. package/docs/templates/index.html +232 -0
  55. package/docs/templates/login.html +286 -0
  56. package/docs/templates/settings.html +365 -0
  57. package/docs/templates/signup.html +350 -0
  58. package/js/accordion.js +192 -0
  59. package/js/combobox.js +263 -0
  60. package/js/menu.js +301 -0
  61. package/js/modal.js +256 -0
  62. package/js/package.json +3 -0
  63. package/js/tabs.js +200 -0
  64. package/js/theme/apply.js +75 -0
  65. package/js/theme/brand-contrast-audit.js +133 -0
  66. package/js/theme/color.js +149 -0
  67. package/js/theme/config-schema.js +40 -0
  68. package/js/theme/contrast.js +76 -0
  69. package/js/theme/export.js +118 -0
  70. package/js/theme/index.js +21 -0
  71. package/js/theme/overlay.js +29 -0
  72. package/js/theme/package.json +3 -0
  73. package/js/theme/palette.js +103 -0
  74. package/js/theme/radius.js +76 -0
  75. package/js/theme/semantic-mapper.js +138 -0
  76. package/js/theme/typography.js +33 -0
  77. package/js/theme/url-state.js +52 -0
  78. package/js/tooltip.js +227 -0
  79. package/package.json +139 -0
@@ -0,0 +1,280 @@
1
+ /* ============================================================
2
+ COMPONENT: Radio Button
3
+ ============================================================ */
4
+
5
+ /* Item wrapper — agrupa radio label + description + helper text
6
+ verticalmente. Use quando precisar de Description/Helper opt-in
7
+ (matches Figma "Show Description"/"Show Helper Text" booleans). */
8
+ .ds-radio-item {
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: var(--ds-radio-content-gap-default);
12
+ }
13
+
14
+ /* Description text — mesmo size do label, regular (Figma) */
15
+ .ds-radio-description {
16
+ font-size: var(--ds-body-font-size-sm);
17
+ font-weight: var(--ds-body-font-weight-regular);
18
+ line-height: var(--ds-body-line-height-sm);
19
+ color: var(--ds-form-field-description-color-default);
20
+ padding-left: calc(var(--ds-size-sm) + var(--ds-space-sm) + var(--ds-space-xs));
21
+ }
22
+
23
+ /* Helper text — menor + mais sutil que description (Figma) */
24
+ .ds-radio-helper {
25
+ font-size: var(--ds-body-font-size-xs);
26
+ font-weight: var(--ds-body-font-weight-regular);
27
+ line-height: var(--ds-body-line-height-xs);
28
+ color: var(--ds-form-field-helper-color-default);
29
+ padding-left: calc(var(--ds-size-sm) + var(--ds-space-sm) + var(--ds-space-xs));
30
+ }
31
+
32
+ /* Radio group container */
33
+ .ds-radio-group {
34
+ border: none;
35
+ padding: 0;
36
+ margin: 0 0 var(--ds-space-md) 0;
37
+ display: flex;
38
+ flex-direction: column;
39
+ gap: var(--ds-space-sm);
40
+ }
41
+
42
+ .ds-radio-group__legend {
43
+ font-family: var(--ds-form-field-label-font-family-default);
44
+ font-size: var(--ds-form-field-label-font-size-default);
45
+ font-weight: var(--ds-body-font-weight-bold);
46
+ line-height: var(--ds-form-field-label-line-height-default);
47
+ color: var(--ds-form-field-label-color-default);
48
+ margin-bottom: var(--ds-space-xs);
49
+ padding: 0;
50
+ }
51
+
52
+ /* Radio item (label wraps input) */
53
+ .ds-radio-label {
54
+ --radio-target-height: var(--ds-radio-target-height-md);
55
+ --radio-control-size: var(--ds-radio-control-size-md);
56
+
57
+ display: inline-flex;
58
+ align-items: center;
59
+ gap: var(--ds-radio-target-gap-default);
60
+ cursor: pointer;
61
+ padding: var(--ds-space-xs) var(--ds-space-xs);
62
+ border-radius: var(--ds-radius-sm);
63
+ min-height: var(--radio-target-height);
64
+ font-size: var(--ds-form-field-label-font-size-default);
65
+ color: var(--ds-form-field-label-color-default);
66
+ }
67
+
68
+ /* Custom radio */
69
+ .ds-radio {
70
+ appearance: none;
71
+ -webkit-appearance: none;
72
+ width: var(--radio-control-size);
73
+ height: var(--radio-control-size);
74
+ border: var(--ds-radio-control-border-width-unselected-default) solid var(--ds-radio-control-border-color-unselected-default);
75
+ border-radius: var(--ds-radio-control-radius-default);
76
+ background-color: var(--ds-radio-control-fill-unselected-default);
77
+ cursor: pointer;
78
+ position: relative;
79
+ flex-shrink: 0;
80
+ transition: border-color var(--ds-motion-duration-fast) var(--ds-motion-ease-default),
81
+ background-color var(--ds-motion-duration-fast) var(--ds-motion-ease-default);
82
+ }
83
+
84
+ .ds-radio::after {
85
+ content: '';
86
+ position: absolute;
87
+ top: 50%;
88
+ left: 50%;
89
+ width: var(--ds-radio-dot-size-md);
90
+ height: var(--ds-radio-dot-size-md);
91
+ border-radius: var(--ds-radio-dot-radius-default);
92
+ background-color: var(--ds-radio-dot-fill-selected-default);
93
+ transform: translate(-50%, -50%) scale(0);
94
+ transition: transform var(--ds-motion-duration-fast) var(--ds-motion-ease-default);
95
+ }
96
+
97
+ /* Checked */
98
+ .ds-radio:checked {
99
+ background-color: var(--ds-radio-control-fill-selected-default);
100
+ border-color: var(--ds-radio-control-border-color-selected-default);
101
+ border-width: var(--ds-radio-control-border-width-selected-default);
102
+ }
103
+
104
+ .ds-radio:checked::after {
105
+ transform: translate(-50%, -50%) scale(1);
106
+ }
107
+
108
+ /* Hover */
109
+ .ds-radio:hover:not(:disabled) {
110
+ background-color: var(--ds-radio-control-fill-unselected-hover);
111
+ border-color: var(--ds-radio-control-border-color-unselected-hover);
112
+ }
113
+
114
+ .ds-radio:checked:hover:not(:disabled) {
115
+ background-color: var(--ds-radio-control-fill-selected-hover);
116
+ border-color: var(--ds-radio-control-border-color-selected-hover);
117
+ }
118
+
119
+ .ds-radio:checked:hover:not(:disabled)::after {
120
+ background-color: var(--ds-radio-dot-fill-selected-hover);
121
+ }
122
+
123
+ /* Focus */
124
+ .ds-radio:focus-visible {
125
+ outline: var(--ds-focus-ring-width) solid var(--ds-focus-ring-color-default);
126
+ outline-offset: var(--ds-focus-ring-width);
127
+ }
128
+
129
+ /* Disabled */
130
+ .ds-radio:disabled {
131
+ background-color: var(--ds-radio-control-fill-unselected-disabled);
132
+ border-color: var(--ds-radio-control-border-color-unselected-disabled);
133
+ cursor: not-allowed;
134
+ }
135
+
136
+ .ds-radio:checked:disabled {
137
+ background-color: var(--ds-radio-control-fill-selected-disabled);
138
+ border-width: 0;
139
+ }
140
+
141
+ .ds-radio:checked:disabled::after {
142
+ background-color: var(--ds-radio-dot-fill-selected-disabled);
143
+ }
144
+
145
+ .ds-radio-label:has(.ds-radio:disabled) {
146
+ cursor: not-allowed;
147
+ color: var(--ds-form-field-label-color-disabled);
148
+ }
149
+
150
+ /* Error state */
151
+ .ds-radio-group--error .ds-radio {
152
+ border-color: var(--ds-radio-control-border-color-unselected-error);
153
+ }
154
+
155
+ .ds-radio-group__error {
156
+ font-size: var(--ds-form-field-error-font-size-default);
157
+ font-weight: var(--ds-form-field-error-font-weight-default);
158
+ line-height: var(--ds-form-field-error-line-height-default);
159
+ color: var(--ds-form-field-error-color-default);
160
+ margin-top: var(--ds-space-xs);
161
+ display: none;
162
+ }
163
+
164
+ .ds-radio-group--error .ds-radio-group__error {
165
+ display: block;
166
+ }
167
+
168
+ /* ---------------------------------------------------------
169
+ Sizes
170
+ --------------------------------------------------------- */
171
+
172
+ /* Small */
173
+ .ds-radio-label:has(.ds-radio--sm) {
174
+ --radio-target-height: var(--ds-radio-target-height-sm);
175
+ --radio-control-size: var(--ds-radio-control-size-sm);
176
+ }
177
+
178
+ .ds-radio--sm {
179
+ width: var(--ds-radio-control-size-sm);
180
+ height: var(--ds-radio-control-size-sm);
181
+ }
182
+
183
+ .ds-radio--sm::after {
184
+ width: var(--ds-radio-dot-size-sm);
185
+ height: var(--ds-radio-dot-size-sm);
186
+ }
187
+
188
+ /* Large */
189
+ .ds-radio-label:has(.ds-radio--lg) {
190
+ --radio-target-height: var(--ds-radio-target-height-lg);
191
+ --radio-control-size: var(--ds-radio-control-size-lg);
192
+ }
193
+
194
+ .ds-radio--lg {
195
+ width: var(--ds-radio-control-size-lg);
196
+ height: var(--ds-radio-control-size-lg);
197
+ }
198
+
199
+ .ds-radio--lg::after {
200
+ width: var(--ds-radio-dot-size-lg);
201
+ height: var(--ds-radio-dot-size-lg);
202
+ }
203
+
204
+ /* ---------------------------------------------------------
205
+ Field anatomy — Content frame, Description, Helper Text
206
+ --------------------------------------------------------- */
207
+
208
+ /*
209
+ HTML structure:
210
+ <label class="ds-radio-label">
211
+ <input type="radio" class="ds-radio">
212
+ <span class="ds-radio__content">
213
+ <span class="ds-radio__label">Rótulo</span>
214
+ <span class="ds-radio__description">Descrição</span>
215
+ <span class="ds-radio__helper">Texto auxiliar</span>
216
+ </span>
217
+ </label>
218
+
219
+ Accessibility:
220
+ - Label hidden + Description visible → aria-labelledby on <input> pointing to .ds-radio__description id
221
+ - Helper Text → aria-describedby on <input> pointing to .ds-radio__helper id
222
+ */
223
+
224
+ /* Vertical stack: Label → Description → Helper Text */
225
+ .ds-radio__content {
226
+ display: flex;
227
+ flex-direction: column;
228
+ gap: var(--ds-radio-content-gap-default);
229
+ min-width: 0;
230
+ }
231
+
232
+ /* Label text — defaults para Md size (label/md: 14px Bold / 20px) */
233
+ .ds-radio__label {
234
+ font-family: var(--ds-form-field-label-font-family-default);
235
+ font-size: var(--ds-form-field-label-font-size-default);
236
+ font-weight: var(--ds-body-font-weight-bold);
237
+ line-height: var(--ds-form-field-label-line-height-default);
238
+ color: var(--ds-form-field-label-color-default);
239
+ }
240
+
241
+ /* Sm size: label = control/label-md (14px Bold / 16px) */
242
+ .ds-radio-label:has(.ds-radio--sm) .ds-radio__label {
243
+ line-height: var(--ds-body-line-height-2xs);
244
+ }
245
+
246
+ /* Lg size: label = label/lg (16px Bold / 24px) */
247
+ .ds-radio-label:has(.ds-radio--lg) .ds-radio__label {
248
+ font-size: var(--ds-body-font-size-md);
249
+ line-height: var(--ds-body-line-height-md);
250
+ }
251
+
252
+ /* Description (body/sm: 14px Regular / 20px) */
253
+ .ds-radio__description {
254
+ font-size: var(--ds-body-font-size-sm);
255
+ font-weight: var(--ds-body-font-weight-regular);
256
+ line-height: var(--ds-body-line-height-sm);
257
+ color: var(--ds-form-field-description-color-default);
258
+ white-space: pre-wrap;
259
+ }
260
+
261
+ /* Helper text (caption/sm: 11px regular / 18px) */
262
+ .ds-radio__helper {
263
+ font-size: var(--ds-body-font-size-xs);
264
+ font-weight: var(--ds-body-font-weight-regular);
265
+ line-height: var(--ds-body-line-height-xs);
266
+ color: var(--ds-form-field-helper-color-default);
267
+ }
268
+
269
+ .ds-radio-label:has(.ds-radio:disabled) .ds-radio__label {
270
+ color: var(--ds-form-field-label-color-disabled);
271
+ }
272
+
273
+ /* ---------------------------------------------------------
274
+ Reduced motion
275
+ --------------------------------------------------------- */
276
+ @media (prefers-reduced-motion: reduce) {
277
+ .ds-radio-label,
278
+ .ds-radio,
279
+ .ds-radio::after { transition: none; }
280
+ }
@@ -0,0 +1,399 @@
1
+ /* ==========================================================================
2
+ Select – .ds-select — aligned with Figma specs
3
+ Sizes: sm=32px, md=40px, lg=48px
4
+ ========================================================================== */
5
+
6
+ /* Wrapper
7
+ ========================================================================== */
8
+
9
+ .ds-select {
10
+ --select-padding-x: var(--ds-select-padding-x-md);
11
+ --select-padding-y: var(--ds-field-padding-y-md);
12
+ --select-gap: var(--ds-select-gap-md);
13
+ --select-chevron-frame-size: var(--ds-select-chevron-size-md);
14
+ --select-icon-frame-size: var(--ds-select-icon-size-md);
15
+ --select-border-width: var(--ds-field-border-width);
16
+ --select-field-leading-size: 0px;
17
+ --select-field-leading-gap: 0px;
18
+
19
+ position: relative;
20
+ display: flex;
21
+ align-items: center;
22
+ gap: var(--ds-select-gap-md);
23
+ height: var(--ds-select-height-md);
24
+ padding: var(--ds-field-padding-y-md) var(--ds-select-padding-x-md);
25
+ border: var(--ds-field-border-width) solid var(--ds-field-border-color-default);
26
+ border-radius: var(--ds-field-radius);
27
+ background: var(--ds-field-bg-default);
28
+ color: var(--ds-field-value-color-default);
29
+ font-family: var(--ds-select-text-font-family-default);
30
+ font-size: var(--ds-select-text-font-size-md);
31
+ font-weight: var(--ds-select-text-font-weight-default);
32
+ letter-spacing: var(--ds-select-text-letter-spacing-default);
33
+ line-height: var(--ds-select-text-line-height-md);
34
+ transition: border-color var(--ds-motion-duration-fast) var(--ds-motion-ease-default),
35
+ box-shadow var(--ds-motion-duration-fast) var(--ds-motion-ease-default);
36
+ }
37
+
38
+ /* Sizes
39
+ ========================================================================== */
40
+
41
+ .ds-select,
42
+ .ds-select--md {
43
+ height: var(--ds-select-height-md);
44
+ gap: var(--ds-select-gap-md);
45
+ padding: var(--ds-field-padding-y-md) var(--ds-select-padding-x-md);
46
+ font-size: var(--ds-select-text-font-size-md);
47
+ line-height: var(--ds-select-text-line-height-md);
48
+ }
49
+
50
+ .ds-select--sm {
51
+ --select-padding-x: var(--ds-select-padding-x-sm);
52
+ --select-padding-y: var(--ds-field-padding-y-sm);
53
+ --select-gap: var(--ds-select-gap-sm);
54
+ --select-chevron-frame-size: var(--ds-select-chevron-size-sm);
55
+ --select-icon-frame-size: var(--ds-select-icon-size-sm);
56
+
57
+ height: var(--ds-select-height-sm);
58
+ gap: var(--ds-select-gap-sm);
59
+ padding: var(--ds-field-padding-y-sm) var(--ds-select-padding-x-sm);
60
+ font-size: var(--ds-select-text-font-size-sm);
61
+ line-height: var(--ds-select-text-line-height-sm);
62
+ }
63
+
64
+ .ds-select--lg {
65
+ --select-padding-x: var(--ds-select-padding-x-lg);
66
+ --select-padding-y: var(--ds-field-padding-y-lg);
67
+ --select-gap: var(--ds-select-gap-lg);
68
+ --select-chevron-frame-size: var(--ds-select-chevron-size-lg);
69
+ --select-icon-frame-size: var(--ds-select-icon-size-lg);
70
+
71
+ height: var(--ds-select-height-lg);
72
+ gap: var(--ds-select-gap-lg);
73
+ padding: var(--ds-field-padding-y-lg) var(--ds-select-padding-x-lg);
74
+ font-size: var(--ds-select-text-font-size-lg);
75
+ line-height: var(--ds-select-text-line-height-lg);
76
+ }
77
+
78
+ /* Field (native select)
79
+ ========================================================================== */
80
+
81
+ .ds-select__field {
82
+ flex: 1;
83
+ align-self: stretch;
84
+ appearance: none;
85
+ -webkit-appearance: none;
86
+ border: none;
87
+ background: transparent;
88
+ outline: none;
89
+ color: var(--ds-field-value-color-default);
90
+ font: inherit;
91
+ letter-spacing: inherit;
92
+ line-height: inherit;
93
+ cursor: pointer;
94
+ min-width: 0;
95
+ margin-top: calc(-1 * (var(--select-padding-y) + var(--select-border-width)));
96
+ margin-bottom: calc(-1 * (var(--select-padding-y) + var(--select-border-width)));
97
+ margin-left: calc(
98
+ -1 * (
99
+ var(--select-padding-x) +
100
+ var(--select-border-width) +
101
+ var(--select-field-leading-size) +
102
+ var(--select-field-leading-gap)
103
+ )
104
+ );
105
+ margin-right: calc(-1 * (var(--select-padding-x) + var(--select-border-width)));
106
+ padding-left: calc(
107
+ var(--select-padding-x) +
108
+ var(--select-border-width) +
109
+ var(--select-field-leading-size) +
110
+ var(--select-field-leading-gap) +
111
+ var(--ds-select-text-frame-padding-x-default)
112
+ );
113
+ padding-right: calc(
114
+ var(--select-padding-x) +
115
+ var(--select-border-width) +
116
+ var(--select-chevron-frame-size) +
117
+ var(--ds-select-chevron-frame-padding-x-default) +
118
+ var(--ds-select-chevron-frame-padding-x-default) +
119
+ var(--select-gap) +
120
+ var(--ds-select-text-frame-padding-x-default)
121
+ );
122
+ }
123
+
124
+ .ds-select:has(.ds-select__icon) {
125
+ --select-field-leading-size: calc(
126
+ var(--select-icon-frame-size) +
127
+ var(--ds-select-icon-frame-padding-x-default) +
128
+ var(--ds-select-icon-frame-padding-x-default)
129
+ );
130
+ --select-field-leading-gap: var(--select-gap);
131
+ }
132
+
133
+ .ds-select__field:invalid,
134
+ .ds-select__field option:disabled[value=""],
135
+ .ds-select__field option[value=""] {
136
+ color: var(--ds-field-placeholder-color-default);
137
+ }
138
+
139
+ .ds-select:has(.ds-select__field option:checked[value=""]) .ds-select__field {
140
+ color: var(--ds-field-placeholder-color-default);
141
+ }
142
+
143
+ .ds-select--disabled:has(.ds-select__field option:checked[value=""]) .ds-select__field,
144
+ .ds-select:has(.ds-select__field:disabled option:checked[value=""]) .ds-select__field {
145
+ color: var(--ds-field-placeholder-color-disabled);
146
+ }
147
+
148
+ /* Chevron indicator
149
+ ========================================================================== */
150
+
151
+ .ds-select__arrow {
152
+ --select-chevron-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
153
+
154
+ position: absolute;
155
+ right: var(--ds-select-padding-x-md);
156
+ top: 50%;
157
+ box-sizing: content-box;
158
+ width: var(--ds-select-chevron-size-md);
159
+ height: var(--ds-select-chevron-size-md);
160
+ padding-left: var(--ds-select-chevron-frame-padding-x-default);
161
+ padding-right: var(--ds-select-chevron-frame-padding-x-default);
162
+ transform: translateY(-50%);
163
+ pointer-events: none;
164
+ color: var(--ds-select-chevron-color-default);
165
+ line-height: 1;
166
+ background-color: currentColor;
167
+ -webkit-mask: var(--select-chevron-mask) center / var(--ds-select-chevron-size-md) var(--ds-select-chevron-size-md) no-repeat;
168
+ mask: var(--select-chevron-mask) center / var(--ds-select-chevron-size-md) var(--ds-select-chevron-size-md) no-repeat;
169
+ }
170
+
171
+ .ds-select--sm .ds-select__arrow {
172
+ right: var(--ds-select-padding-x-sm);
173
+ width: var(--ds-select-chevron-size-sm);
174
+ height: var(--ds-select-chevron-size-sm);
175
+ -webkit-mask-size: var(--ds-select-chevron-size-sm) var(--ds-select-chevron-size-sm);
176
+ mask-size: var(--ds-select-chevron-size-sm) var(--ds-select-chevron-size-sm);
177
+ }
178
+
179
+ .ds-select--lg .ds-select__arrow {
180
+ right: var(--ds-select-padding-x-lg);
181
+ width: var(--ds-select-chevron-size-lg);
182
+ height: var(--ds-select-chevron-size-lg);
183
+ -webkit-mask-size: var(--ds-select-chevron-size-lg) var(--ds-select-chevron-size-lg);
184
+ mask-size: var(--ds-select-chevron-size-lg) var(--ds-select-chevron-size-lg);
185
+ }
186
+
187
+ /* Icon
188
+ ========================================================================== */
189
+
190
+ .ds-select__icon {
191
+ flex-shrink: 0;
192
+ display: inline-flex;
193
+ align-items: center;
194
+ justify-content: center;
195
+ box-sizing: content-box;
196
+ width: var(--ds-select-icon-size-md);
197
+ height: var(--ds-select-icon-size-md);
198
+ padding-left: var(--ds-select-icon-frame-padding-x-default);
199
+ padding-right: var(--ds-select-icon-frame-padding-x-default);
200
+ color: var(--ds-select-icon-color-default);
201
+ fill: none;
202
+ stroke: currentColor;
203
+ stroke-width: var(--ds-select-icon-stroke-width-md);
204
+ font-size: var(--ds-select-icon-size-md);
205
+ line-height: 1;
206
+ pointer-events: none;
207
+ }
208
+
209
+ .ds-select--sm .ds-select__icon {
210
+ width: var(--ds-select-icon-size-sm);
211
+ height: var(--ds-select-icon-size-sm);
212
+ font-size: var(--ds-select-icon-size-sm);
213
+ stroke-width: var(--ds-select-icon-stroke-width-sm);
214
+ }
215
+
216
+ .ds-select--lg .ds-select__icon {
217
+ width: var(--ds-select-icon-size-lg);
218
+ height: var(--ds-select-icon-size-lg);
219
+ font-size: var(--ds-select-icon-size-lg);
220
+ stroke-width: var(--ds-select-icon-stroke-width-lg);
221
+ }
222
+
223
+ /* States
224
+ ========================================================================== */
225
+
226
+ /* Hover */
227
+ .ds-select:hover:not(.ds-select--disabled):not(:focus-within) {
228
+ border-color: var(--ds-field-border-color-hover);
229
+ }
230
+
231
+ /* Focused */
232
+ .ds-select:focus-within {
233
+ background: var(--ds-field-bg-default);
234
+ border-color: var(--ds-field-border-color-focus);
235
+ border-radius: var(--ds-field-radius);
236
+ outline: var(--ds-focus-ring-width) solid var(--ds-focus-ring-color-default);
237
+ outline-offset: var(--ds-focus-ring-width);
238
+ }
239
+
240
+ /* Filled */
241
+ .ds-select--filled {
242
+ background: var(--ds-field-bg-default);
243
+ border-color: var(--ds-field-border-color-filled);
244
+ }
245
+
246
+ .ds-select--filled .ds-select__field {
247
+ color: var(--ds-field-value-color-default);
248
+ }
249
+
250
+ /* Error */
251
+ .ds-select--error,
252
+ .ds-field--error .ds-select {
253
+ background: var(--ds-field-bg-default);
254
+ border-color: var(--ds-field-border-color-error);
255
+ }
256
+
257
+ .ds-select--error:hover:not(.ds-select--disabled):not(:focus-within),
258
+ .ds-field--error .ds-select:hover:not(.ds-select--disabled):not(:focus-within) {
259
+ background: var(--ds-field-bg-default);
260
+ border-color: var(--ds-field-border-color-error-hover);
261
+ }
262
+
263
+ .ds-select--error .ds-select__field,
264
+ .ds-select--error .ds-select__field:invalid,
265
+ .ds-field--error .ds-select .ds-select__field,
266
+ .ds-field--error .ds-select .ds-select__field:invalid {
267
+ color: var(--ds-field-value-color-default);
268
+ }
269
+
270
+ .ds-select--error:focus-within,
271
+ .ds-field--error .ds-select:focus-within {
272
+ border-color: var(--ds-field-border-color-error);
273
+ outline-color: var(--ds-focus-ring-color-error);
274
+ }
275
+
276
+ /* Disabled */
277
+ .ds-select--disabled,
278
+ .ds-select:has(.ds-select__field:disabled) {
279
+ background: var(--ds-field-bg-disabled);
280
+ border-color: var(--ds-field-border-color-disabled);
281
+ color: var(--ds-field-value-color-disabled);
282
+ pointer-events: none;
283
+ }
284
+
285
+ .ds-select--disabled .ds-select__field,
286
+ .ds-select__field:disabled {
287
+ color: var(--ds-field-value-color-disabled);
288
+ opacity: 1;
289
+ }
290
+
291
+ .ds-select--disabled .ds-select__field:invalid,
292
+ .ds-select__field:disabled:invalid {
293
+ color: var(--ds-field-placeholder-color-disabled);
294
+ }
295
+
296
+ .ds-select--disabled .ds-select__arrow,
297
+ .ds-select:has(.ds-select__field:disabled) .ds-select__arrow {
298
+ color: var(--ds-select-chevron-color-disabled);
299
+ }
300
+
301
+ .ds-select--disabled .ds-select__icon,
302
+ .ds-select:has(.ds-select__field:disabled) .ds-select__icon {
303
+ color: var(--ds-select-icon-color-disabled);
304
+ }
305
+
306
+ /* Readonly */
307
+ .ds-select--readonly {
308
+ background: var(--ds-field-bg-readonly);
309
+ border-color: var(--ds-field-border-color-readonly);
310
+ }
311
+
312
+ .ds-select--readonly .ds-select__field {
313
+ color: var(--ds-field-value-color-readonly);
314
+ }
315
+
316
+ .ds-select--readonly:focus-within {
317
+ background: var(--ds-field-bg-readonly);
318
+ border-color: var(--ds-field-border-color-readonly);
319
+ outline-color: var(--ds-focus-ring-color-readonly);
320
+ }
321
+
322
+ /* Composed field anatomy
323
+ ========================================================================== */
324
+
325
+ .ds-field:has(.ds-select) {
326
+ gap: var(--ds-form-field-stack-gap-default);
327
+ }
328
+
329
+ .ds-field:has(.ds-select) .ds-field__label-row {
330
+ gap: var(--ds-form-field-label-row-gap-default);
331
+ }
332
+
333
+ .ds-field:has(.ds-select) .ds-field__label {
334
+ color: var(--ds-form-field-label-color-default);
335
+ font-family: var(--ds-form-field-label-font-family-default);
336
+ font-size: var(--ds-form-field-label-font-size-default);
337
+ font-weight: var(--ds-body-font-weight-bold);
338
+ letter-spacing: var(--ds-body-letter-spacing-normal);
339
+ line-height: var(--ds-form-field-label-line-height-default);
340
+ }
341
+
342
+ .ds-field:has(.ds-select--sm) .ds-field__label {
343
+ font-size: var(--ds-form-field-label-font-size-default);
344
+ line-height: var(--ds-form-field-label-line-height-default);
345
+ }
346
+
347
+ .ds-field:has(.ds-select--lg) .ds-field__label {
348
+ font-size: var(--ds-form-field-label-font-size-default);
349
+ line-height: var(--ds-form-field-label-line-height-default);
350
+ }
351
+
352
+ .ds-field:has(.ds-select) .ds-field__required {
353
+ color: var(--ds-form-field-required-color-default);
354
+ font-family: var(--ds-form-field-required-font-family-default);
355
+ font-size: var(--ds-form-field-required-font-size-default);
356
+ font-weight: var(--ds-body-font-weight-bold);
357
+ letter-spacing: var(--ds-body-letter-spacing-normal);
358
+ line-height: var(--ds-form-field-required-line-height-default);
359
+ }
360
+
361
+ .ds-field:has(.ds-select) .ds-field__helper {
362
+ color: var(--ds-form-field-helper-color-default);
363
+ font-family: var(--ds-form-field-label-font-family-default);
364
+ font-size: var(--ds-body-font-size-xs);
365
+ font-weight: var(--ds-body-font-weight-regular);
366
+ letter-spacing: var(--ds-body-letter-spacing-normal);
367
+ line-height: var(--ds-body-line-height-xs);
368
+ }
369
+
370
+ .ds-field:has(.ds-select--sm) .ds-field__helper {
371
+ font-size: var(--ds-body-font-size-xs);
372
+ line-height: var(--ds-body-line-height-xs);
373
+ }
374
+
375
+ .ds-field:has(.ds-select--lg) .ds-field__helper {
376
+ font-size: var(--ds-body-font-size-xs);
377
+ line-height: var(--ds-body-line-height-xs);
378
+ }
379
+
380
+ .ds-field--error:has(.ds-select) .ds-field__label {
381
+ color: var(--ds-form-field-label-color-default);
382
+ }
383
+
384
+ .ds-field:has(.ds-select--disabled) .ds-field__helper,
385
+ .ds-field:has(.ds-select__field:disabled) .ds-field__helper {
386
+ color: var(--ds-form-field-helper-color-disabled);
387
+ }
388
+
389
+ /* ---------------------------------------------------------
390
+ Error message styling lives em form-field.css.
391
+ Compor Select dentro de .ds-field pra usar o pattern composto.
392
+ --------------------------------------------------------- */
393
+
394
+ /* ---------------------------------------------------------
395
+ Reduced motion
396
+ --------------------------------------------------------- */
397
+ @media (prefers-reduced-motion: reduce) {
398
+ .ds-select { transition: none; }
399
+ }