@pure-ds/storybook 0.1.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 (129) hide show
  1. package/.storybook/addons/description/preview.js +15 -0
  2. package/.storybook/addons/description/register.js +60 -0
  3. package/.storybook/addons/html-preview/Panel.jsx +327 -0
  4. package/.storybook/addons/html-preview/constants.js +6 -0
  5. package/.storybook/addons/html-preview/preview.js +178 -0
  6. package/.storybook/addons/html-preview/register.js +16 -0
  7. package/.storybook/addons/pds-configurator/SearchTool.js +44 -0
  8. package/.storybook/addons/pds-configurator/Tool.js +30 -0
  9. package/.storybook/addons/pds-configurator/constants.js +9 -0
  10. package/.storybook/addons/pds-configurator/preview.js +159 -0
  11. package/.storybook/addons/pds-configurator/register.js +24 -0
  12. package/.storybook/docs.css +35 -0
  13. package/.storybook/htmlPreview.css +103 -0
  14. package/.storybook/htmlPreview.js +271 -0
  15. package/.storybook/main.js +160 -0
  16. package/.storybook/preview-body.html +48 -0
  17. package/.storybook/preview-head.html +11 -0
  18. package/.storybook/preview.js +1563 -0
  19. package/README.md +266 -0
  20. package/bin/index.js +40 -0
  21. package/dist/pds-reference.json +2101 -0
  22. package/package.json +45 -0
  23. package/pds.config.js +6 -0
  24. package/public/assets/css/app.css +1216 -0
  25. package/public/assets/data/auto-design-advanced.json +704 -0
  26. package/public/assets/data/auto-design-simple.json +123 -0
  27. package/public/assets/img/icon-512x512.png +0 -0
  28. package/public/assets/img/logo-trans.png +0 -0
  29. package/public/assets/img/logo.png +0 -0
  30. package/public/assets/js/app.js +15088 -0
  31. package/public/assets/js/app.js.map +7 -0
  32. package/public/assets/js/lit.js +1176 -0
  33. package/public/assets/js/lit.js.map +7 -0
  34. package/public/assets/js/pds.js +9801 -0
  35. package/public/assets/js/pds.js.map +7 -0
  36. package/public/assets/pds/components/pds-calendar.js +837 -0
  37. package/public/assets/pds/components/pds-drawer.js +857 -0
  38. package/public/assets/pds/components/pds-icon.js +338 -0
  39. package/public/assets/pds/components/pds-jsonform.js +1775 -0
  40. package/public/assets/pds/components/pds-richtext.js +1035 -0
  41. package/public/assets/pds/components/pds-scrollrow.js +331 -0
  42. package/public/assets/pds/components/pds-splitpanel.js +401 -0
  43. package/public/assets/pds/components/pds-tabstrip.js +251 -0
  44. package/public/assets/pds/components/pds-toaster.js +446 -0
  45. package/public/assets/pds/components/pds-upload.js +657 -0
  46. package/public/assets/pds/custom-elements.json +2003 -0
  47. package/public/assets/pds/icons/pds-icons.svg +498 -0
  48. package/public/assets/pds/pds-css-complete.json +1861 -0
  49. package/public/assets/pds/pds-runtime-config.json +11 -0
  50. package/public/assets/pds/pds.css-data.json +2152 -0
  51. package/public/assets/pds/styles/pds-components.css +1944 -0
  52. package/public/assets/pds/styles/pds-components.css.js +3895 -0
  53. package/public/assets/pds/styles/pds-primitives.css +352 -0
  54. package/public/assets/pds/styles/pds-primitives.css.js +711 -0
  55. package/public/assets/pds/styles/pds-styles.css +3761 -0
  56. package/public/assets/pds/styles/pds-styles.css.js +7529 -0
  57. package/public/assets/pds/styles/pds-tokens.css +699 -0
  58. package/public/assets/pds/styles/pds-tokens.css.js +1405 -0
  59. package/public/assets/pds/styles/pds-utilities.css +763 -0
  60. package/public/assets/pds/styles/pds-utilities.css.js +1533 -0
  61. package/public/assets/pds/vscode-custom-data.json +824 -0
  62. package/scripts/build-pds-reference.mjs +807 -0
  63. package/scripts/generate-stories.js +542 -0
  64. package/scripts/package-build.js +86 -0
  65. package/src/js/app.js +17 -0
  66. package/src/js/common/ask.js +208 -0
  67. package/src/js/common/common.js +20 -0
  68. package/src/js/common/font-loader.js +200 -0
  69. package/src/js/common/msg.js +90 -0
  70. package/src/js/lit.js +40 -0
  71. package/src/js/pds-core/pds-config.js +1162 -0
  72. package/src/js/pds-core/pds-enhancer-metadata.js +75 -0
  73. package/src/js/pds-core/pds-enhancers.js +357 -0
  74. package/src/js/pds-core/pds-enums.js +86 -0
  75. package/src/js/pds-core/pds-generator.js +5317 -0
  76. package/src/js/pds-core/pds-ontology.js +256 -0
  77. package/src/js/pds-core/pds-paths.js +109 -0
  78. package/src/js/pds-core/pds-query.js +571 -0
  79. package/src/js/pds-core/pds-registry.js +129 -0
  80. package/src/js/pds-core/pds.d.ts +129 -0
  81. package/src/js/pds.d.ts +408 -0
  82. package/src/js/pds.js +1579 -0
  83. package/src/pds-core/pds-api.js +105 -0
  84. package/stories/GettingStarted.md +96 -0
  85. package/stories/GettingStarted.stories.js +144 -0
  86. package/stories/WhatIsPDS.md +194 -0
  87. package/stories/WhatIsPDS.stories.js +144 -0
  88. package/stories/components/PdsCalendar.stories.js +263 -0
  89. package/stories/components/PdsDrawer.stories.js +623 -0
  90. package/stories/components/PdsIcon.stories.js +78 -0
  91. package/stories/components/PdsJsonform.stories.js +1444 -0
  92. package/stories/components/PdsRichtext.stories.js +367 -0
  93. package/stories/components/PdsScrollrow.stories.js +140 -0
  94. package/stories/components/PdsSplitpanel.stories.js +502 -0
  95. package/stories/components/PdsTabstrip.stories.js +442 -0
  96. package/stories/components/PdsToaster.stories.js +186 -0
  97. package/stories/components/PdsUpload.stories.js +66 -0
  98. package/stories/enhancements/Dropdowns.stories.js +185 -0
  99. package/stories/enhancements/InteractiveStates.stories.js +625 -0
  100. package/stories/enhancements/MeshGradients.stories.js +320 -0
  101. package/stories/enhancements/OpenGroups.stories.js +227 -0
  102. package/stories/enhancements/RangeSliders.stories.js +232 -0
  103. package/stories/enhancements/RequiredFields.stories.js +189 -0
  104. package/stories/enhancements/Toggles.stories.js +167 -0
  105. package/stories/foundations/Colors.stories.js +283 -0
  106. package/stories/foundations/Icons.stories.js +305 -0
  107. package/stories/foundations/SmartSurfaces.stories.js +367 -0
  108. package/stories/foundations/Spacing.stories.js +175 -0
  109. package/stories/foundations/Typography.stories.js +960 -0
  110. package/stories/foundations/ZIndex.stories.js +325 -0
  111. package/stories/patterns/BorderEffects.stories.js +72 -0
  112. package/stories/patterns/Layout.stories.js +99 -0
  113. package/stories/patterns/Utilities.stories.js +107 -0
  114. package/stories/primitives/Accordion.stories.js +359 -0
  115. package/stories/primitives/Alerts.stories.js +64 -0
  116. package/stories/primitives/Badges.stories.js +183 -0
  117. package/stories/primitives/Buttons.stories.js +229 -0
  118. package/stories/primitives/Cards.stories.js +353 -0
  119. package/stories/primitives/FormGroups.stories.js +569 -0
  120. package/stories/primitives/Forms.stories.js +131 -0
  121. package/stories/primitives/Media.stories.js +203 -0
  122. package/stories/primitives/Tables.stories.js +232 -0
  123. package/stories/reference/ReferenceCatalog.stories.js +28 -0
  124. package/stories/reference/reference-catalog.js +413 -0
  125. package/stories/reference/reference-docs.js +302 -0
  126. package/stories/reference/reference-helpers.js +310 -0
  127. package/stories/utilities/GridSystem.stories.js +208 -0
  128. package/stories/utils/PdsAsk.stories.js +420 -0
  129. package/stories/utils/toast-utils.js +148 -0
@@ -0,0 +1,3895 @@
1
+ // Pure Design System - components
2
+ // Auto-generated - do not edit directly
3
+
4
+ export const components = new CSSStyleSheet();
5
+ components.replaceSync(`@layer components {
6
+
7
+ /* Semantic HTML Elements (low-specificity via :where()) */
8
+
9
+ :where(blockquote) {
10
+ margin: 0 0 var(--spacing-4) 0;
11
+ padding: var(--spacing-4) var(--spacing-6);
12
+ border-left: 4px solid var(--color-primary-500);
13
+ background-color: var(--color-surface-subtle);
14
+ border-radius: var(--radius-md);
15
+ font-style: italic;
16
+ color: var(--color-text-secondary);
17
+
18
+ :where(p):last-child {
19
+ margin-bottom: 0;
20
+ }
21
+
22
+ :where(cite) {
23
+ display: block;
24
+ margin-top: var(--spacing-2);
25
+ font-size: var(--font-size-sm);
26
+ font-style: normal;
27
+ color: var(--color-text-tertiary);
28
+
29
+ &::before {
30
+ content: "— ";
31
+ }
32
+ }
33
+ }
34
+
35
+ :where(hr) {
36
+ margin: var(--spacing-8) 0;
37
+ border: none;
38
+ border-top: 1px solid var(--color-border);
39
+ height: 0;
40
+ }
41
+
42
+ :where(dl) {
43
+ margin: 0 0 var(--spacing-4) 0;
44
+ }
45
+
46
+ :where(dt) {
47
+ font-weight: var(--font-weight-semibold);
48
+ color: var(--color-text-primary);
49
+ margin-top: var(--spacing-3);
50
+
51
+ &:first-child {
52
+ margin-top: 0;
53
+ }
54
+ }
55
+
56
+ :where(dd) {
57
+ margin: var(--spacing-1) 0 var(--spacing-3) var(--spacing-6);
58
+ color: var(--color-text-secondary);
59
+ }
60
+
61
+ :where(nav), :where(header), :where(footer) {
62
+ display: block;
63
+ }
64
+
65
+ :where(header), :where(footer) {
66
+ width: 100%;
67
+ }
68
+
69
+ :where(article), :where(section), :where(aside) {
70
+ display: block;
71
+ margin-bottom: var(--spacing-6);
72
+
73
+ & > *:last-child {
74
+ margin-bottom: 0;
75
+ }
76
+ }
77
+
78
+ :where(mark) {
79
+ background-color: var(--color-warning-200);
80
+ color: var(--color-warning-900);
81
+ padding: 0 var(--spacing-1);
82
+ border-radius: var(--radius-sm);
83
+ }
84
+
85
+ :where(kbd) {
86
+ display: inline-block;
87
+ padding: var(--spacing-1) var(--spacing-2);
88
+ font-family: var(--font-family-mono);
89
+ font-size: var(--font-size-sm);
90
+ color: var(--color-text-primary);
91
+ background-color: var(--color-surface-elevated);
92
+ border: 1px solid var(--color-border);
93
+ border-radius: var(--radius-sm);
94
+ box-shadow: 0 2px 0 0 var(--color-border);
95
+ }
96
+
97
+ :where(abbr[title]) {
98
+ text-decoration: underline dotted;
99
+ cursor: help;
100
+ text-decoration-thickness: 1px;
101
+ }
102
+
103
+ :where(time) {
104
+ font-variant-numeric: tabular-nums;
105
+ }
106
+
107
+ :where(address) {
108
+ font-style: normal;
109
+ line-height: var(--font-line-height-relaxed);
110
+ margin: 0 0 var(--spacing-4) 0;
111
+ }
112
+
113
+ :where(details):not(.accordion *) {
114
+ margin: 0 0 var(--spacing-2) 0;
115
+ border: 1px solid var(--color-border);
116
+ border-radius: var(--radius-md);
117
+ background-color: var(--color-surface-base);
118
+
119
+ &[open] :where(summary) {
120
+ border-bottom: 1px solid var(--color-border);
121
+ background-color: var(--color-surface-subtle);
122
+
123
+ &::after {
124
+ transform: rotate(270deg);
125
+ }
126
+ }
127
+
128
+ & > *:not(:where(summary)) {
129
+ padding: var(--spacing-4);
130
+ }
131
+ }
132
+
133
+ :where(summary) {
134
+ padding: var(--spacing-3) var(--spacing-4);
135
+ cursor: pointer;
136
+ border-radius: var(--radius-md);
137
+ font-weight: var(--font-weight-medium);
138
+ user-select: none;
139
+ list-style: none;
140
+ display: flex;
141
+ align-items: center;
142
+ justify-content: space-between;
143
+ transition: background-color var(--transition-fast);
144
+
145
+ &::-webkit-details-marker {
146
+ display: none;
147
+ }
148
+
149
+ &::after {
150
+ content: "›";
151
+ display: inline-block;
152
+ transform: rotate(90deg);
153
+ transition: transform var(--transition-fast);
154
+ font-size: var(--font-size-xl);
155
+ font-weight: var(--font-weight-bold);
156
+ color: var(--color-text-secondary);
157
+ }
158
+
159
+ &:hover {
160
+ background-color: var(--color-surface-subtle);
161
+ }
162
+ }
163
+
164
+ /* Dialog styles moved to #generateDialogStyles() */
165
+
166
+
167
+
168
+ /* Mobile-First Form Styles - Generated from Design Config */
169
+ form {
170
+ margin: 0;
171
+ width: 100%;
172
+ }
173
+
174
+ fieldset {
175
+ margin: 0 0 var(--spacing-2) 0;
176
+ padding: var(--spacing-5);
177
+ width: 100%;
178
+ background-color: color-mix(in oklab, var(--color-surface-subtle) 50%, transparent 50%);
179
+
180
+ /* Unified styling for radio groups and checkbox groups */
181
+ &[role="radiogroup"],
182
+ &[role="group"] {
183
+ display: flex;
184
+ flex-direction: column;
185
+ gap: var(--spacing-2);
186
+ padding: 0;
187
+ background-color: transparent;
188
+
189
+ label {
190
+ display: flex;
191
+ align-items: center;
192
+ gap: var(--spacing-3);
193
+ padding: var(--spacing-1) 0;
194
+ cursor: pointer;
195
+ min-height: auto;
196
+ border: none;
197
+ background: none;
198
+ font-weight: var(--font-weight-normal);
199
+ margin-bottom: 0;
200
+
201
+ &:hover {
202
+ color: var(--color-primary-700);
203
+ }
204
+ }
205
+
206
+ input[type="radio"],
207
+ input[type="checkbox"] {
208
+ position: static;
209
+ opacity: 1;
210
+ width: var(--spacing-5);
211
+ height: var(--spacing-5);
212
+ min-height: var(--spacing-5);
213
+ margin: 0;
214
+ cursor: pointer;
215
+ flex-shrink: 0;
216
+ accent-color: var(--color-primary-600);
217
+ appearance: auto;
218
+ -webkit-appearance: auto;
219
+ -moz-appearance: auto;
220
+
221
+ &:focus {
222
+ outline: 2px solid var(--color-primary-500);
223
+ outline-offset: 2px;
224
+ }
225
+ }
226
+ }
227
+
228
+ }
229
+
230
+
231
+
232
+ /* Nested legend scaling: reduce font-size for deeper sub-forms */
233
+ fieldset > legend { font-size: var(--font-size-lg); }
234
+ fieldset fieldset > legend { font-size: var(--font-size-base); }
235
+ fieldset fieldset fieldset > legend { font-size: var(--font-size-sm); }
236
+
237
+ .form-container {
238
+ display: grid;
239
+ gap: var(--spacing-6);
240
+ width: 100%;
241
+ }
242
+
243
+ .fields {
244
+ display: grid;
245
+ gap: var(--spacing-4);
246
+ }
247
+
248
+ label {
249
+ display: block;
250
+ margin-bottom: var(--spacing-3);
251
+ font-weight: var(--font-weight-medium);
252
+ color: var(--color-text-primary);
253
+ font-size: var(--font-size-sm);
254
+ line-height: var(--font-line-height-normal);
255
+ }
256
+
257
+ [data-label] {
258
+ display: block;
259
+ font-weight: var(--font-weight-medium);
260
+ color: var(--color-text-primary);
261
+ font-size: var(--font-size-sm);
262
+ margin-bottom: var(--spacing-2);
263
+ }
264
+
265
+ [data-open]{
266
+ [data-label]{
267
+ margin-bottom: 0;
268
+ }
269
+ }
270
+
271
+ .field-description {
272
+ font-size: var(--font-size-xs);
273
+ color: var(--color-text-secondary);
274
+ margin-top: var(--spacing-1);
275
+ line-height: var(--font-line-height-relaxed);
276
+ }
277
+
278
+ input, textarea, select {
279
+ width: 100%;
280
+ min-height: 40px;
281
+ padding: calc(var(--spacing-1) * 0.75) var(--spacing-4);
282
+ border: 1px solid var(--color-border);
283
+ border-radius: var(--radius-md);
284
+ font-family: var(--font-family-body);
285
+ font-size: var(--font-size-base);
286
+ line-height: var(--font-line-height-normal);
287
+ background-color: var(--color-input-bg);
288
+ color: var(--color-text-primary);
289
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast);
290
+ touch-action: manipulation;
291
+ appearance: none;
292
+ -webkit-appearance: none;
293
+
294
+ &:focus {
295
+ outline: none;
296
+ border-color: var(--color-primary-500);
297
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
298
+ background-color: var(--color-surface-base);
299
+ }
300
+
301
+ &:disabled {
302
+ background-color: var(--color-input-disabled-bg);
303
+ color: var(--color-input-disabled-text);
304
+ border-color: var(--color-border);
305
+ cursor: not-allowed;
306
+ opacity: 0.6;
307
+ }
308
+
309
+ &:invalid {
310
+ border-color: var(--color-danger-500);
311
+
312
+ &:focus {
313
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-danger-500) 30%, transparent);
314
+ }
315
+ }
316
+ }
317
+
318
+ input[type="range"] {
319
+ padding: 0;
320
+ background: transparent;
321
+ min-height: auto;
322
+ }
323
+
324
+ /* Make range visually match other inputs */
325
+ input[type="range"] {
326
+ -webkit-appearance: none;
327
+ appearance: none;
328
+ height: var(--input-min-height, 40px); /* align control height with inputs */
329
+ width: 100%;
330
+ }
331
+
332
+ /* Track and thumb styling - using CSS nesting to reduce repetition */
333
+ input[type="range"] {
334
+ /* WebKit track */
335
+ &::-webkit-slider-runnable-track {
336
+ height: var(--range-track-height, 8px);
337
+ background: var(--color-input-bg);
338
+ border-radius: var(--radius-full);
339
+ }
340
+
341
+ /* WebKit thumb */
342
+ &::-webkit-slider-thumb {
343
+ -webkit-appearance: none;
344
+ appearance: none;
345
+ width: var(--range-thumb-size, 28px);
346
+ height: var(--range-thumb-size, 28px);
347
+ margin-top: calc((var(--range-track-height, 8px) - var(--range-thumb-size, 28px)) / 2);
348
+ background: color-mix(in srgb, var(--color-primary-500) 15%, var(--color-surface-base));
349
+ border-radius: 50%;
350
+ box-shadow: var(--shadow-sm);
351
+ cursor: grab;
352
+ border: 1px solid color-mix(in srgb, var(--color-primary-500) 30%, var(--color-border));
353
+ }
354
+
355
+ /* Mozilla track */
356
+ &::-moz-range-track {
357
+ height: var(--range-track-height, 8px);
358
+ background: var(--color-input-bg);
359
+ border-radius: var(--radius-full);
360
+ }
361
+
362
+ /* Mozilla thumb */
363
+ &::-moz-range-thumb {
364
+ width: var(--range-thumb-size, 28px);
365
+ height: var(--range-thumb-size, 28px);
366
+ background: color-mix(in srgb, var(--color-primary-500) 15%, var(--color-surface-base));
367
+ border-radius: 50%;
368
+ box-shadow: var(--shadow-sm);
369
+ border: 1px solid color-mix(in srgb, var(--color-primary-500) 30%, var(--color-border));
370
+ transform: translateY(calc((var(--range-track-height, 8px) - var(--range-thumb-size, 28px)) / 2));
371
+ }
372
+
373
+ /* Hover and focus states for WebKit */
374
+ &:hover::-webkit-slider-thumb,
375
+ &:focus-visible::-webkit-slider-thumb {
376
+ cursor: grabbing;
377
+ background: var(--color-primary-500);
378
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
379
+ border-color: var(--color-primary-600);
380
+ }
381
+
382
+ /* Active state for WebKit */
383
+ &:active::-webkit-slider-thumb {
384
+ background: var(--color-primary-600);
385
+ }
386
+
387
+ /* Hover and focus states for Mozilla */
388
+ &:hover::-moz-range-thumb,
389
+ &:focus-visible::-moz-range-thumb {
390
+ background: var(--color-primary-500);
391
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
392
+ border-color: var(--color-primary-600);
393
+ cursor: grabbing;
394
+ }
395
+
396
+ /* Active state for Mozilla */
397
+ &:active::-moz-range-thumb {
398
+ background: var(--color-primary-600);
399
+ }
400
+ }
401
+
402
+ /* Focus style for container to match input focus */
403
+ .range-container:focus-within {
404
+ border-color: var(--color-primary-500);
405
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary-500) 30%, transparent);
406
+ }
407
+
408
+ input[type="range"]:active::-moz-range-thumb {
409
+ background: var(--color-primary-600);
410
+ }
411
+
412
+ input[type="color"] {
413
+ -webkit-appearance: none;
414
+ padding: 0;
415
+ width: 3rem;
416
+ height: 3rem;
417
+ border-radius: 0.75rem; /* your radius */
418
+ overflow: hidden; /* important */
419
+ cursor: pointer;
420
+
421
+ /* The wrapper */
422
+ &::-webkit-color-swatch-wrapper {
423
+ padding: 0;
424
+ border-radius: inherit;
425
+ }
426
+
427
+ /* The swatch (the actual color box) */
428
+ &::-webkit-color-swatch {
429
+ border: none;
430
+ border-radius: inherit;
431
+ }
432
+ }
433
+
434
+ /* Button-style checkbox inputs outside of fieldsets */
435
+ .checkbox-container input[type="checkbox"] {
436
+ appearance: none;
437
+ -webkit-appearance: none;
438
+ -moz-appearance: none;
439
+ position: absolute;
440
+ opacity: 0;
441
+ width: 0;
442
+ height: 0;
443
+ margin: 0;
444
+ padding: 0;
445
+ pointer-events: none;
446
+ }
447
+
448
+ label:has(input[type="checkbox"]):not(fieldset label):not(label[data-toggle]),
449
+ input[type="checkbox"] + label:not(fieldset label):not(label[data-toggle]) {
450
+ display: inline-flex;
451
+ align-items: center;
452
+ justify-content: center;
453
+ min-height: calc(44px * 0.75);
454
+ padding: calc(var(--spacing-1) * 0.6) calc(var(--spacing-4) * 0.85);
455
+ border: 1px solid var(--color-border);
456
+ border-radius: var(--radius-md);
457
+ font-family: var(--font-family-body);
458
+ font-size: var(--font-size-sm);
459
+ font-weight: var(--font-weight-medium);
460
+ line-height: 1.2;
461
+ cursor: pointer;
462
+ transition: all var(--transition-fast);
463
+ text-decoration: none;
464
+ touch-action: manipulation;
465
+ user-select: none;
466
+ background-color: transparent;
467
+ color: var(--color-text-primary);
468
+ margin: 0;
469
+ flex: 0 1 auto;
470
+ white-space: nowrap;
471
+
472
+ &:hover {
473
+ background-color: var(--color-surface-subtle);
474
+ border-color: var(--color-primary-500);
475
+ }
476
+ }
477
+
478
+ label:has(input[type="checkbox"]:checked):not(fieldset label):not(label[data-toggle]),
479
+ input[type="checkbox"]:checked + label:not(fieldset label):not(label[data-toggle]) {
480
+ background-color: color-mix(in oklab, var(--color-primary-500) 8%, transparent);
481
+ color: var(--color-primary-700);
482
+ border-color: var(--color-primary-500);
483
+ border-width: 2px;
484
+ font-weight: var(--font-weight-semibold);
485
+
486
+ &:hover {
487
+ background-color: color-mix(in oklab, var(--color-primary-500) 15%, transparent);
488
+ border-color: var(--color-primary-600);
489
+ }
490
+ }
491
+
492
+ label:has(input[type="checkbox"]:focus):not(fieldset label):not(label[data-toggle]),
493
+ input[type="checkbox"]:focus + label:not(fieldset label):not(label[data-toggle]) {
494
+ outline: none;
495
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
496
+ }
497
+
498
+ label:has(input[type="checkbox"]:disabled):not(fieldset label):not(label[data-toggle]),
499
+ input[type="checkbox"]:disabled + label:not(fieldset label):not(label[data-toggle]) {
500
+ background-color: var(--color-input-disabled-bg);
501
+ color: var(--color-input-disabled-text);
502
+ border-color: var(--color-border);
503
+ cursor: not-allowed;
504
+ opacity: 0.6;
505
+ }
506
+
507
+ label:has(input[type="checkbox"]:checked:disabled):not(fieldset label):not(label[data-toggle]),
508
+ input[type="checkbox"]:checked:disabled + label:not(fieldset label):not(label[data-toggle]) {
509
+ background-color: var(--color-input-disabled-bg);
510
+ color: var(--color-input-disabled-text);
511
+ border-color: var(--color-border);
512
+ }
513
+
514
+ /* Keep default checkbox/radio for inputs NOT in special containers */
515
+ input[type="checkbox"]:not(fieldset input[type="checkbox"]):not(.checkbox-container input[type="checkbox"]),
516
+ input[type="radio"]:not(fieldset input[type="radio"]) {
517
+ width: var(--spacing-5);
518
+ height: var(--spacing-5);
519
+ min-height: var(--spacing-5);
520
+ margin-right: var(--spacing-2);
521
+ cursor: pointer;
522
+ position: static;
523
+ opacity: 1;
524
+ appearance: auto;
525
+ -webkit-appearance: auto;
526
+
527
+ &:disabled {
528
+ cursor: not-allowed;
529
+ }
530
+ }
531
+
532
+ /* Button-style radio and checkbox groups with .buttons class */
533
+ fieldset[role="radiogroup"].buttons,
534
+ fieldset[role="group"].buttons {
535
+ flex-direction: row;
536
+ flex-wrap: wrap;
537
+ gap: var(--spacing-3);
538
+
539
+ input[type="radio"],
540
+ input[type="checkbox"] {
541
+ appearance: none;
542
+ -webkit-appearance: none;
543
+ -moz-appearance: none;
544
+ position: absolute;
545
+ opacity: 0;
546
+ width: 0;
547
+ height: 0;
548
+ margin: 0;
549
+ padding: 0;
550
+ pointer-events: none;
551
+ }
552
+
553
+ label {
554
+ display: inline-flex;
555
+ align-items: center;
556
+ justify-content: center;
557
+ min-height: calc(44px * 0.75);
558
+ padding: calc(var(--spacing-1) * 0.6) calc(var(--spacing-4) * 0.85);
559
+ border: 1px solid var(--color-border);
560
+ border-radius: var(--radius-md);
561
+ font-family: var(--font-family-body);
562
+ font-size: var(--font-size-sm);
563
+ font-weight: var(--font-weight-medium);
564
+ line-height: 1.2;
565
+ cursor: pointer;
566
+ transition: all var(--transition-fast);
567
+ text-decoration: none;
568
+ touch-action: manipulation;
569
+ user-select: none;
570
+ background-color: transparent;
571
+ color: var(--color-text-primary);
572
+ margin: 0;
573
+ flex: 0 1 auto;
574
+ white-space: nowrap;
575
+
576
+ &:hover {
577
+ background-color: var(--color-surface-subtle);
578
+ border-color: var(--color-primary-500);
579
+ color: var(--color-text-primary);
580
+ }
581
+
582
+ &:has([disabled]){
583
+ pointer-events: none;
584
+ }
585
+ }
586
+
587
+ label:has(input[type="radio"]:checked),
588
+ label:has(input[type="checkbox"]:checked) {
589
+ background-color: color-mix(in oklab, var(--color-primary-500) 8%, transparent);
590
+ border-color: var(--color-primary-500);
591
+ border-width: 2px;
592
+ font-weight: var(--font-weight-semibold);
593
+
594
+ &:hover {
595
+ background-color: color-mix(in oklab, var(--color-primary-500) 15%, transparent);
596
+ border-color: var(--color-primary-600);
597
+ }
598
+ }
599
+
600
+ label:has(input[type="radio"]:focus),
601
+ label:has(input[type="checkbox"]:focus) {
602
+ outline: none;
603
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
604
+ }
605
+
606
+ label:has(input[type="radio"]:disabled),
607
+ label:has(input[type="checkbox"]:disabled) {
608
+ background-color: var(--color-input-disabled-bg);
609
+ color: var(--color-input-disabled-text);
610
+ border-color: var(--color-border);
611
+ cursor: not-allowed;
612
+ opacity: 0.6;
613
+ }
614
+
615
+ label:has(input[type="radio"]:checked:disabled),
616
+ label:has(input[type="checkbox"]:checked:disabled) {
617
+ background-color: var(--color-input-disabled-bg);
618
+ color: var(--color-input-disabled-text);
619
+ border-color: var(--color-border);
620
+ }
621
+ }
622
+
623
+ /* Toggle switches - enhanced checkboxes with data-toggle attribute */
624
+ label[data-toggle] {
625
+ display: inline-flex;
626
+ align-items: normal;
627
+ gap: var(--spacing-3);
628
+ cursor: pointer;
629
+ user-select: none;
630
+ padding: 0;
631
+ background: transparent;
632
+ border: none;
633
+ min-height: auto;
634
+ font-weight: var(--font-weight-normal);
635
+
636
+ /* Hide the original checkbox in toggle switches */
637
+ input[type="checkbox"] {
638
+ display: none;
639
+ }
640
+
641
+ /* Toggle switch container */
642
+ .toggle-switch {
643
+ position: relative;
644
+ display: inline-block;
645
+ width: 44px;
646
+ height: 24px;
647
+ background-color: var(--color-gray-300);
648
+ border-radius: var(--radius-full);
649
+ transition: background-color 200ms ease;
650
+ cursor: pointer;
651
+ flex-shrink: 0;
652
+ }
653
+
654
+ /* Toggle switch knob */
655
+ .toggle-knob {
656
+ position: absolute;
657
+ top: 2px;
658
+ left: 2px;
659
+ width: 20px;
660
+ height: 20px;
661
+ background-color: #ffffff;
662
+ border-radius: 50%;
663
+ transition: left 200ms ease;
664
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
665
+ }
666
+
667
+ /* Toggle switch when checked - using :has() selector */
668
+ &:has(input[type="checkbox"]:checked) .toggle-switch {
669
+ background-color: var(--color-primary-fill);
670
+ }
671
+
672
+
673
+ /* Toggle knob when checked - always moves to the right */
674
+ &:has(input[type="checkbox"]:checked) .toggle-knob {
675
+ left: 22px;
676
+ }
677
+
678
+ /* Focus state for toggle switch */
679
+ &:has(input[type="checkbox"]:focus) .toggle-switch {
680
+ outline: 2px solid var(--color-primary-500);
681
+ outline-offset: 2px;
682
+ }
683
+
684
+ /* Focus visible state when label is focused via keyboard */
685
+ &:focus-visible .toggle-switch {
686
+ outline: 2px solid var(--color-primary-500);
687
+ outline-offset: 2px;
688
+ }
689
+
690
+ /* Remove default outline on label itself */
691
+ &:focus {
692
+ outline: none;
693
+ }
694
+
695
+ /* Disabled state */
696
+ &:has(input[type="checkbox"]:disabled) {
697
+ cursor: not-allowed;
698
+ opacity: 0.6;
699
+
700
+ .toggle-switch {
701
+ opacity: 0.5;
702
+ cursor: not-allowed;
703
+ }
704
+ }
705
+ }
706
+
707
+ input[type="file"] {
708
+ padding: var(--spacing-2) var(--spacing-4);
709
+ cursor: pointer;
710
+ }
711
+
712
+ /* Textareas */
713
+ textarea {
714
+ min-height: calc(var(--spacing-4) * 5);
715
+ padding: var(--spacing-3) var(--spacing-4);
716
+ resize: vertical;
717
+ line-height: var(--font-line-height-relaxed);
718
+ }
719
+
720
+ /* Select dropdowns */
721
+ select {
722
+ cursor: pointer;
723
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
724
+ background-position: right var(--spacing-2) center;
725
+ background-repeat: no-repeat;
726
+ background-size: 1.5em 1.5em;
727
+ padding-right: var(--spacing-8);
728
+ }
729
+
730
+ /* Button styling */
731
+ button, .btn, input[type="submit"], input[type="button"], input[type="reset"] {
732
+ display: inline-flex;
733
+ gap: var(--spacing-1);
734
+ align-items: center;
735
+ justify-content: center;
736
+ min-height: 44px;
737
+ padding: calc(var(--spacing-1) * 1) var(--spacing-6);
738
+ border: 1px solid transparent;
739
+ border-radius: var(--radius-md);
740
+ font-family: var(--font-family-body);
741
+ font-size: var(--font-size-base);
742
+ font-weight: var(--font-weight-medium);
743
+ line-height: 1;
744
+ cursor: pointer;
745
+ transition: all var(--transition-fast);
746
+ text-decoration: none;
747
+ touch-action: manipulation;
748
+ user-select: none;
749
+ background-color: var(--color-surface-base);
750
+ color: var(--color-text-primary);
751
+ border-color: var(--color-border);
752
+
753
+ /* Only apply generic hover to non-variant buttons */
754
+ &:hover:not(.btn-primary):not(.btn-secondary):not(.btn-outline) {
755
+ background-color: var(--color-surface-elevated);
756
+ }
757
+
758
+ &:focus {
759
+ outline: none;
760
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
761
+ }
762
+
763
+ &:disabled {
764
+ background-color: var(--color-input-disabled-bg);
765
+ color: var(--color-input-disabled-text);
766
+ border-color: var(--color-input-disabled-bg);
767
+ cursor: not-allowed;
768
+ opacity: 0.6;
769
+ }
770
+ }
771
+
772
+ .btn-primary {
773
+ background-color: var(--color-primary-fill);
774
+ color: white;
775
+ border-color: var(--color-primary-fill);
776
+
777
+ &:hover {
778
+ background-color: color-mix(in oklab, var(--color-primary-fill) 90%, black 10%);
779
+ border-color: color-mix(in oklab, var(--color-primary-fill) 90%, black 10%);
780
+ color: white;
781
+ }
782
+
783
+ &:active {
784
+ background-color: color-mix(in oklab, var(--color-primary-fill) 80%, black 20%);
785
+ border-color: color-mix(in oklab, var(--color-primary-fill) 80%, black 20%);
786
+ color: white;
787
+ }
788
+
789
+ &:focus {
790
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
791
+ }
792
+
793
+ &:disabled {
794
+ background-color: var(--color-input-disabled-bg);
795
+ color: var(--color-input-disabled-text);
796
+ border-color: var(--color-input-disabled-bg);
797
+ }
798
+ }
799
+
800
+ .btn-secondary {
801
+ background-color: var(--color-surface-base);
802
+ color: var(--color-text-primary);
803
+ border-color: var(--color-border);
804
+
805
+ &:hover {
806
+ background-color: var(--color-surface-elevated);
807
+ }
808
+ }
809
+
810
+ .btn-outline {
811
+ background-color: transparent;
812
+ color: var(--color-primary-500);
813
+ border-color: var(--color-primary-500);
814
+
815
+ &:hover {
816
+ background-color: var(--color-primary-500);
817
+ color: var(--color-primary-contrast, #ffffff);
818
+ border-color: var(--color-primary-500);
819
+
820
+ pds-icon {
821
+ color: var(--color-primary-contrast, #ffffff);
822
+ }
823
+ }
824
+
825
+ &:active {
826
+ background-color: color-mix(in oklab, var(--color-primary-500) 80%, black 20%);
827
+ border-color: color-mix(in oklab, var(--color-primary-500) 80%, black 20%);
828
+ color: var(--color-primary-contrast, #ffffff);
829
+
830
+ pds-icon {
831
+ color: var(--color-primary-contrast, #ffffff);
832
+ }
833
+ }
834
+
835
+ &:disabled {
836
+ background-color: transparent;
837
+ color: var(--color-input-disabled-text);
838
+ border-color: var(--color-input-disabled-bg);
839
+ }
840
+ }
841
+
842
+ .btn-sm {
843
+ padding: var(--spacing-2) var(--spacing-4);
844
+ font-size: var(--font-size-sm);
845
+ min-height: calc(44px * 0.8);
846
+ }
847
+
848
+ .btn-xs {
849
+ padding: var(--spacing-1) var(--spacing-2);
850
+ font-size: var(--font-size-xs);
851
+ min-height: calc(44px * 0.6);
852
+ }
853
+
854
+
855
+ .btn-lg {
856
+ padding: var(--spacing-4) var(--spacing-8);
857
+ font-size: var(--font-size-lg);
858
+ min-height: calc(44px * 1.2);
859
+ }
860
+
861
+ /* Working/loading state for buttons */
862
+ button.btn-working,
863
+ a.btn-working {
864
+ cursor: wait;
865
+ pointer-events: none;
866
+ opacity: 0.6;
867
+
868
+ pds-icon:first-child {
869
+ animation: pds-spin 0.8s linear infinite;
870
+ }
871
+ }
872
+
873
+ @keyframes pds-spin {
874
+ to { transform: rotate(360deg); }
875
+ }
876
+
877
+ /* Skeleton loading animation */
878
+ .skeleton {
879
+ background: linear-gradient(
880
+ 90deg,
881
+ color-mix(in oklab, var(--color-surface-base) 92%, var(--color-text-primary) 8%) 0%,
882
+ color-mix(in oklab, var(--color-surface-base) 85%, var(--color-text-primary) 15%) 50%,
883
+ color-mix(in oklab, var(--color-surface-base) 92%, var(--color-text-primary) 8%) 100%
884
+ );
885
+ background-size: 200% 100%;
886
+ animation: pds-skeleton 1.5s ease-in-out infinite;
887
+ border-radius: var(--radius-sm);
888
+
889
+ &::before {
890
+ content: '\\00a0';
891
+ }
892
+ }
893
+
894
+ @keyframes pds-skeleton {
895
+ 0% { background-position: 200% 0; }
896
+ 100% { background-position: -200% 0; }
897
+ }
898
+
899
+ /* Form utility classes */
900
+ .range-container {
901
+ display: flex;
902
+ align-items: center;
903
+ gap: var(--spacing-3);
904
+ width: 100%;
905
+ background: var(--color-input-bg);
906
+ border: 1px solid var(--color-border);
907
+ border-radius: var(--radius-md);
908
+ min-height: var(--input-min-height, 40px);
909
+ position: relative;
910
+
911
+ input[type="range"] {
912
+ border: none;
913
+ }
914
+ }
915
+
916
+ .range-bubble {
917
+ position: absolute;
918
+ top: calc(-1 * (var(--range-thumb-size, 28px) + var(--spacing-2)));
919
+ transform: translateX(-50%);
920
+ min-width: calc(var(--range-thumb-size, 28px) * 0.8);
921
+ padding: var(--spacing-1) var(--spacing-2);
922
+ border-radius: var(--radius-md);
923
+ background: var(--color-surface-base);
924
+ color: var(--color-text-primary);
925
+ text-align: center;
926
+ font-size: var(--font-size-sm);
927
+ box-shadow: var(--shadow-md);
928
+ opacity: 0;
929
+ pointer-events: none;
930
+ transition: opacity 150ms ease, transform 150ms ease;
931
+
932
+ &.visible {
933
+ opacity: 1;
934
+ }
935
+ }
936
+
937
+ /* Anchor bubble to the thumb position using left (set by enhancer)
938
+ and center with translateX(-50%). */
939
+
940
+ /* Array field styling */
941
+ .array-list {
942
+ display: flex;
943
+ flex-direction: column;
944
+ gap: var(--spacing-4);
945
+ margin-bottom: var(--spacing-4);
946
+ }
947
+
948
+ .array-item {
949
+ position: relative;
950
+ padding: var(--spacing-4);
951
+ border: 1px solid var(--color-border);
952
+ border-radius: var(--radius-md);
953
+ background-color: var(--color-surface-base);
954
+
955
+ fieldset {
956
+ background-color: transparent;
957
+ margin-bottom: var(--spacing-3);
958
+
959
+ &:last-of-type {
960
+ margin-bottom: 0;
961
+ }
962
+ }
963
+
964
+ .array-controls {
965
+ padding-top: var(--spacing-3);
966
+ border-top: 1px solid var(--color-border);
967
+ margin-top: var(--spacing-4);
968
+ }
969
+ }
970
+
971
+ .array-controls {
972
+ display: flex;
973
+ gap: var(--spacing-2);
974
+ margin-top: var(--spacing-3);
975
+ flex-wrap: wrap;
976
+
977
+ button {
978
+ padding: var(--spacing-2) var(--spacing-3);
979
+ font-size: var(--font-size-sm);
980
+ min-height: auto;
981
+ }
982
+ }
983
+
984
+ .range-value {
985
+ min-width: var(--spacing-16);
986
+ text-align: right;
987
+ font-weight: var(--font-weight-medium);
988
+ font-size: var(--font-size-sm);
989
+ color: var(--color-text-primary);
990
+ }
991
+
992
+ .checkbox-container {
993
+ display: flex;
994
+ flex-direction: row;
995
+ align-items: center;
996
+ gap: var(--spacing-2);
997
+ flex-wrap: wrap;
998
+
999
+ input[type="checkbox"],
1000
+ input[type="radio"] {
1001
+ position: absolute;
1002
+ opacity: 0;
1003
+ }
1004
+ }
1005
+
1006
+
1007
+
1008
+ /* Alert/Notification Styles */
1009
+
1010
+ /* Alias: .semantic-message shares alert base styles */
1011
+ .alert, .semantic-message {
1012
+ padding: var(--spacing-4);
1013
+ border-radius: var(--radius-md);
1014
+ margin: 0 0 var(--spacing-4) 0;
1015
+ border-left: 4px solid;
1016
+ display: flex;
1017
+ align-items: flex-start;
1018
+ gap: var(--spacing-3);
1019
+ font-size: var(--font-size-sm);
1020
+ line-height: var(--font-line-height-relaxed);
1021
+
1022
+ & > *:last-child {
1023
+ margin-bottom: 0;
1024
+ }
1025
+ }
1026
+ /* Variants: success/info/warning/danger mapped to tokens */
1027
+ .alert-success, .semantic-message.success {
1028
+ background-color: var(--color-success-50);
1029
+ border-color: var(--color-success-600);
1030
+ color: var(--color-success-900);
1031
+ }
1032
+ .alert-info, .semantic-message.info {
1033
+ background-color: var(--color-info-50);
1034
+ border-color: var(--color-info-600);
1035
+ color: var(--color-info-900);
1036
+ }
1037
+ .alert-warning, .semantic-message.warning {
1038
+ background-color: var(--color-warning-50);
1039
+ border-color: var(--color-warning-600);
1040
+ color: var(--color-warning-900);
1041
+ }
1042
+ .alert-danger,
1043
+ .alert-error,
1044
+ .semantic-message.danger {
1045
+ background-color: var(--color-danger-50);
1046
+ border-color: var(--color-danger-600);
1047
+ color: var(--color-danger-900);
1048
+ }
1049
+
1050
+ /* Semantic-message content defaults */
1051
+ .semantic-message strong { display: block; }
1052
+ .semantic-message p { margin: 0; font-size: var(--font-size-sm); }
1053
+
1054
+ .alert-title {
1055
+ font-weight: var(--font-weight-semibold);
1056
+ margin: 0 0 var(--spacing-2) 0;
1057
+ font-size: var(--font-size-base);
1058
+ }
1059
+
1060
+ .alert-icon {
1061
+ flex-shrink: 0;
1062
+ display: flex;
1063
+ align-items: center;
1064
+ justify-content: center;
1065
+
1066
+ pds-icon {
1067
+ flex-shrink: 0;
1068
+ }
1069
+ }
1070
+
1071
+ .alert-dismissible {
1072
+ padding-right: var(--spacing-12);
1073
+ position: relative;
1074
+ }
1075
+
1076
+ .alert-close {
1077
+ position: absolute;
1078
+ top: var(--spacing-3);
1079
+ right: var(--spacing-3);
1080
+ background: none;
1081
+ border: none;
1082
+ font-size: var(--font-size-xl);
1083
+ line-height: 1;
1084
+ opacity: 0.6;
1085
+ cursor: pointer;
1086
+ padding: var(--spacing-1);
1087
+ transition: opacity var(--transition-fast);
1088
+
1089
+ &:hover {
1090
+ opacity: 1;
1091
+ }
1092
+ }
1093
+
1094
+
1095
+
1096
+ /* Badge/Pill Styles */
1097
+
1098
+ .badge {
1099
+ display: inline-flex;
1100
+ align-items: center;
1101
+ justify-content: center;
1102
+ padding: var(--spacing-1) var(--spacing-2);
1103
+ font-size: var(--font-size-xs);
1104
+ font-weight: var(--font-weight-semibold);
1105
+ line-height: 1;
1106
+ border-radius: var(--radius-full);
1107
+ white-space: nowrap;
1108
+ vertical-align: middle;
1109
+ background-color: var(--color-gray-200);
1110
+ color: var(--color-gray-800);
1111
+ border-radius: var(--radius-full);
1112
+ }
1113
+
1114
+ .badge-primary {
1115
+ background-color: var(--color-primary-600);
1116
+ color: white;
1117
+ }
1118
+
1119
+ .badge-secondary {
1120
+ background-color: var(--color-secondary-600);
1121
+ color: white;
1122
+ }
1123
+
1124
+ .badge-success {
1125
+ background-color: var(--color-success-600);
1126
+ color: white;
1127
+ }
1128
+
1129
+ .badge-info {
1130
+ background-color: var(--color-info-600);
1131
+ color: white;
1132
+ }
1133
+
1134
+ .badge-warning {
1135
+ background-color: var(--color-warning-600);
1136
+ color: white;
1137
+ }
1138
+
1139
+ .badge-danger {
1140
+ background-color: var(--color-danger-600);
1141
+ color: white;
1142
+ }
1143
+
1144
+ .badge-outline {
1145
+ background-color: transparent;
1146
+ border: 1px solid currentColor;
1147
+
1148
+ &.badge-primary {
1149
+ color: var(--color-text-primary);
1150
+ }
1151
+
1152
+ &.badge-secondary {
1153
+ color: var(--color-secondary-600);
1154
+ }
1155
+
1156
+ &.badge-success {
1157
+ color: var(--color-success-600);
1158
+ }
1159
+
1160
+ &.badge-info {
1161
+ color: var(--color-info-600);
1162
+ }
1163
+
1164
+ &.badge-warning {
1165
+ color: var(--color-warning-600);
1166
+ }
1167
+
1168
+ &.badge-danger {
1169
+ color: var(--color-danger-600);
1170
+ }
1171
+ }
1172
+
1173
+ .badge-sm {
1174
+ padding: 2px var(--spacing-1);
1175
+ font-size: 10px;
1176
+ }
1177
+
1178
+ .badge-lg {
1179
+ padding: var(--spacing-2) var(--spacing-3);
1180
+ font-size: var(--font-size-sm);
1181
+ }
1182
+
1183
+ .pill {
1184
+ padding: var(--spacing-1) var(--spacing-3);
1185
+ border-radius: var(--radius-full);
1186
+ }
1187
+
1188
+
1189
+
1190
+ /* ============================================================================
1191
+ Dialog Primitive
1192
+ Native <dialog> element with PDS integration
1193
+ ============================================================================ */
1194
+
1195
+ /* Dialog base styles */
1196
+ dialog {
1197
+ position: fixed;
1198
+ inset: 0;
1199
+ max-width: min(600px, calc(100vw - var(--spacing-8)));
1200
+ max-height: calc(100vh - var(--spacing-8));
1201
+ margin: auto;
1202
+ padding: 0;
1203
+ border: none;
1204
+ border-radius: var(--radius-lg);
1205
+
1206
+ /* Surface styling - elevated overlay */
1207
+ background-color: var(--surface-overlay-bg);
1208
+ color: var(--surface-overlay-text);
1209
+ box-shadow: 0 8px 32px var(--surface-overlay-shadow);
1210
+
1211
+ /* Smooth transitions */
1212
+ opacity: 0;
1213
+ scale: 0.95;
1214
+ transition:
1215
+ opacity 0.2s ease,
1216
+ scale 0.2s ease,
1217
+ overlay 0.2s ease allow-discrete,
1218
+ display 0.2s ease allow-discrete;
1219
+
1220
+ /* Overflow handling */
1221
+ overflow: hidden;
1222
+ }
1223
+
1224
+ /* Open state */
1225
+ dialog[open] {
1226
+ opacity: 1;
1227
+ scale: 1;
1228
+ }
1229
+
1230
+ /* Starting style for smooth open animation */
1231
+ @starting-style {
1232
+ dialog[open] {
1233
+ opacity: 0;
1234
+ scale: 0.95;
1235
+ }
1236
+ }
1237
+
1238
+ /* Backdrop styling */
1239
+ dialog::backdrop {
1240
+ background: var(--backdrop-bg);
1241
+ backdrop-filter: var(--backdrop-filter);
1242
+ opacity: 0;
1243
+ transition:
1244
+ opacity 0.2s ease,
1245
+ overlay 0.2s ease allow-discrete,
1246
+ display 0.2s ease allow-discrete;
1247
+ }
1248
+
1249
+ dialog[open]::backdrop {
1250
+ opacity: var(--backdrop-opacity, 1);
1251
+ }
1252
+
1253
+ @starting-style {
1254
+ dialog[open]::backdrop {
1255
+ opacity: 0;
1256
+ }
1257
+ }
1258
+
1259
+ /* Form structure - use flexbox instead of contents */
1260
+ dialog form {
1261
+ display: flex;
1262
+ flex-direction: column;
1263
+ height: 100%;
1264
+ margin: 0;
1265
+ }
1266
+
1267
+ /* Dialog fields - to open pds-jsonform subforms */
1268
+ .dialog-field {
1269
+ margin-top: var(--spacing-3);
1270
+ }
1271
+
1272
+ /* Dialog header */
1273
+ dialog {
1274
+ header,
1275
+ form > header {
1276
+ display: flex;
1277
+ align-items: center;
1278
+ justify-content: space-between;
1279
+ gap: var(--spacing-4);
1280
+ padding: var(--spacing-6);
1281
+ border-bottom: 1px solid var(--surface-overlay-border);
1282
+ flex-shrink: 0;
1283
+
1284
+ h2,
1285
+ h3 {
1286
+ margin: 0;
1287
+ font-size: var(--font-size-lg);
1288
+ font-weight: var(--font-weight-semibold);
1289
+ color: var(--surface-overlay-text);
1290
+ flex: 1;
1291
+ }
1292
+
1293
+ /* Close button in header */
1294
+ button[value="cancel"],
1295
+ .dialog-close {
1296
+ background: none;
1297
+ border: none;
1298
+ padding: var(--spacing-2);
1299
+ border-radius: var(--radius-sm);
1300
+ cursor: pointer;
1301
+ color: var(--surface-overlay-icon);
1302
+ transition: background-color var(--transition-fast);
1303
+ display: inline-flex;
1304
+ align-items: center;
1305
+ justify-content: center;
1306
+
1307
+ &:hover {
1308
+ background-color: var(--color-surface-subtle);
1309
+ }
1310
+
1311
+ &:focus-visible {
1312
+ outline: 2px solid var(--color-focus-ring);
1313
+ outline-offset: 2px;
1314
+ }
1315
+ }
1316
+ }
1317
+
1318
+ /* Dialog body - scrollable content */
1319
+ article,
1320
+ form > article,
1321
+ .dialog-body {
1322
+ flex: 1;
1323
+ padding: var(--spacing-6);
1324
+ overflow-y: auto;
1325
+ overflow-x: hidden;
1326
+ }
1327
+
1328
+ /* Dialog footer - actions */
1329
+ footer,
1330
+ form > footer {
1331
+ display: flex;
1332
+ flex-direction: row;
1333
+ gap: var(--spacing-3);
1334
+ justify-content: flex-end;
1335
+ align-items: center;
1336
+ padding: var(--spacing-6);
1337
+ border-top: 1px solid var(--surface-overlay-border);
1338
+ flex-shrink: 0;
1339
+ }
1340
+ }
1341
+
1342
+ /* Dialog size modifiers */
1343
+ dialog.dialog-sm {
1344
+ max-width: min(400px, calc(100vw - var(--spacing-8)));
1345
+ }
1346
+
1347
+ dialog.dialog-lg {
1348
+ max-width: min(800px, calc(100vw - var(--spacing-8)));
1349
+ }
1350
+
1351
+ dialog.dialog-xl {
1352
+ max-width: min(1200px, calc(100vw - var(--spacing-8)));
1353
+ }
1354
+
1355
+ dialog.dialog-full {
1356
+ max-width: calc(100vw - var(--spacing-8));
1357
+ max-height: calc(100vh - var(--spacing-8));
1358
+ }
1359
+
1360
+ /* Mobile responsiveness */
1361
+ @media (max-width: 639px) {
1362
+ dialog {
1363
+ max-width: 100vw;
1364
+ max-height: 100vh;
1365
+ border-radius: 0;
1366
+ top: 50%;
1367
+ transform: translateY(-50%);
1368
+ margin: 0;
1369
+ }
1370
+
1371
+ dialog header,
1372
+ dialog form > header,
1373
+ dialog article,
1374
+ dialog form > article,
1375
+ dialog footer,
1376
+ dialog form > footer {
1377
+ padding: var(--spacing-4);
1378
+ }
1379
+ }
1380
+
1381
+ /* Reduced motion support */
1382
+ @media (prefers-reduced-motion: reduce) {
1383
+ dialog,
1384
+ dialog::backdrop {
1385
+ transition-duration: 0.01s !important;
1386
+ }
1387
+ }
1388
+
1389
+
1390
+
1391
+ /* Accordion (details/summary) */
1392
+
1393
+ .accordion {
1394
+ --_acc-radius: var(--radius-md);
1395
+ --_acc-border: 1px solid var(--color-border);
1396
+ --_acc-bg: var(--color-surface-base);
1397
+
1398
+ details {
1399
+ border: var(--_acc-border);
1400
+ border-radius: var(--_acc-radius);
1401
+ background: var(--_acc-bg);
1402
+ margin: 0 0 var(--spacing-3) 0;
1403
+
1404
+ &[open] {
1405
+ & > summary::after {
1406
+ transform: rotate(45deg);
1407
+ }
1408
+
1409
+ &::details-content {
1410
+ block-size: auto;
1411
+ }
1412
+ }
1413
+
1414
+ /* Modern approach: animate block-size with ::details-content */
1415
+ &::details-content {
1416
+ block-size: 0;
1417
+ overflow: hidden;
1418
+ transition: block-size var(--transition-normal) ease, content-visibility var(--transition-normal);
1419
+ transition-behavior: allow-discrete;
1420
+ }
1421
+
1422
+ /* Content padding (works for both approaches) */
1423
+ & > :not(summary) > * {
1424
+ padding-inline: var(--spacing-4);
1425
+ padding-block: var(--spacing-3);
1426
+ }
1427
+ }
1428
+
1429
+ summary {
1430
+ cursor: pointer;
1431
+ padding: var(--spacing-3) var(--spacing-4);
1432
+ list-style: none;
1433
+ outline: none;
1434
+ display: flex;
1435
+ align-items: center;
1436
+ gap: var(--spacing-2);
1437
+
1438
+ &::-webkit-details-marker {
1439
+ display: none;
1440
+ }
1441
+
1442
+ /* Chevron indicator */
1443
+ &::after {
1444
+ content: "";
1445
+ margin-inline-start: auto;
1446
+ inline-size: 0.7em;
1447
+ block-size: 0.7em;
1448
+ border-inline-end: 2px solid currentColor;
1449
+ border-block-end: 2px solid currentColor;
1450
+ transform: rotate(-45deg);
1451
+ transition: transform var(--transition-normal);
1452
+ }
1453
+ }
1454
+ }
1455
+
1456
+ /* Fallback: grid trick for browsers without ::details-content support */
1457
+ @supports not selector(::details-content) {
1458
+ .accordion details {
1459
+ & > :not(summary) {
1460
+ display: grid;
1461
+ grid-template-rows: 0fr;
1462
+ transition: grid-template-rows var(--transition-normal) ease;
1463
+ overflow: hidden;
1464
+
1465
+ & > * {
1466
+ min-block-size: 0;
1467
+ }
1468
+ }
1469
+
1470
+ &[open] > :not(summary) {
1471
+ grid-template-rows: 1fr;
1472
+ }
1473
+ }
1474
+ }
1475
+
1476
+
1477
+ /* Dropdown Component */
1478
+
1479
+ /* Basic dropdown host */
1480
+ nav[data-dropdown] {
1481
+ position: relative;
1482
+ display: inline-block;
1483
+ padding: 0;
1484
+
1485
+ menu {
1486
+ position: absolute;
1487
+ list-style: none;
1488
+ padding: var(--spacing-2);
1489
+ margin: 0;
1490
+ background: var(--color-surface-overlay);
1491
+ border: 1px solid var(--color-border);
1492
+ border-radius: var(--radius-md);
1493
+ box-shadow: var(--shadow-lg);
1494
+ top: 100%;
1495
+ bottom: auto;
1496
+ left: 0;
1497
+ right: auto;
1498
+ margin-top: var(--spacing-2);
1499
+ --dropdown-transition-duration: var(--transition-fast, 160ms);
1500
+ min-width: max(100%, var(--dropdown-min-width, 12rem));
1501
+ width: max-content;
1502
+ opacity: 0;
1503
+ scale: 0.95;
1504
+ visibility: hidden;
1505
+ display: none;
1506
+ pointer-events: none;
1507
+ transform-origin: top center;
1508
+ z-index: var(--z-dropdown, 1050);
1509
+ max-height: min(60vh, 24rem);
1510
+ overflow-y: auto;
1511
+ transition:
1512
+ opacity var(--dropdown-transition-duration) ease,
1513
+ scale var(--dropdown-transition-duration) ease,
1514
+ visibility 0s linear var(--dropdown-transition-duration),
1515
+ display 0s linear var(--dropdown-transition-duration);
1516
+ transition-behavior: allow-discrete;
1517
+ }
1518
+
1519
+ menu[aria-hidden="false"] {
1520
+ display: block;
1521
+ opacity: 1;
1522
+ scale: 1;
1523
+ visibility: visible;
1524
+ pointer-events: auto;
1525
+ transition:
1526
+ opacity var(--dropdown-transition-duration) ease,
1527
+ scale var(--dropdown-transition-duration) ease,
1528
+ visibility 0s linear 0s,
1529
+ display 0s linear 0s;
1530
+ }
1531
+
1532
+ li {
1533
+ padding: var(--spacing-1) 0;
1534
+
1535
+ & + li {
1536
+ border-top: 1px solid var(--color-border);
1537
+ margin-top: var(--spacing-2);
1538
+ }
1539
+
1540
+ &:has(> hr) {
1541
+ border-top: none;
1542
+ margin-top: 0;
1543
+ padding: 0;
1544
+
1545
+ & + li {
1546
+ border-top: none;
1547
+ margin-top: 0;
1548
+ }
1549
+ }
1550
+
1551
+ & > hr {
1552
+ border: none;
1553
+ border-top: 3px solid var(--color-border);
1554
+ margin: var(--spacing-2) 0;
1555
+ }
1556
+ }
1557
+
1558
+ a {
1559
+ display: flex;
1560
+ color: var(--color-text-primary);
1561
+ text-decoration: none;
1562
+ align-items: center;
1563
+ gap: var(--spacing-2);
1564
+
1565
+ &.danger {
1566
+ color: var(--color-danger-600);
1567
+ }
1568
+ }
1569
+
1570
+ &.align-right,
1571
+ &[data-align="right"],
1572
+ &[data-align="end"],
1573
+ &[data-dropdown-align="right"],
1574
+ &[data-dropdown-align="end"] {
1575
+ menu {
1576
+ left: auto;
1577
+ right: 0;
1578
+ }
1579
+ }
1580
+
1581
+ &[data-mode="up"],
1582
+ &[data-dropdown-direction="up"] {
1583
+ menu {
1584
+ top: auto;
1585
+ bottom: 100%;
1586
+ margin-top: 0;
1587
+ margin-bottom: var(--spacing-2);
1588
+ transform-origin: bottom center;
1589
+ }
1590
+ }
1591
+
1592
+ &[data-mode="down"],
1593
+ &[data-dropdown-direction="down"] {
1594
+ menu {
1595
+ top: 100%;
1596
+ bottom: auto;
1597
+ margin-top: var(--spacing-2);
1598
+ margin-bottom: 0;
1599
+ transform-origin: top center;
1600
+ }
1601
+ }
1602
+
1603
+ &[data-mode="auto"] menu {
1604
+ top: 100%;
1605
+ bottom: auto;
1606
+ }
1607
+
1608
+ @media (prefers-reduced-motion: reduce) {
1609
+ menu {
1610
+ transition-duration: 0.01s !important;
1611
+ }
1612
+ }
1613
+ }
1614
+
1615
+ @starting-style {
1616
+ nav[data-dropdown] menu[aria-hidden="false"] {
1617
+ opacity: 0;
1618
+ scale: 0.95;
1619
+ }
1620
+ }
1621
+
1622
+
1623
+ /* Tab Strip Component */
1624
+
1625
+ /* Tab navigation */
1626
+
1627
+ pds-tabstrip {
1628
+ margin-top: var(--spacing-6);
1629
+
1630
+ & > nav {
1631
+ display: flex;
1632
+ gap: var(--spacing-1);
1633
+ border-bottom: 2px solid var(--color-border);
1634
+ margin-bottom: var(--spacing-6);
1635
+ position: relative;
1636
+ overflow-x: auto;
1637
+ overflow-y: hidden;
1638
+ scrollbar-width: none; /* Firefox */
1639
+ -ms-overflow-style: none; /* IE/Edge */
1640
+
1641
+ &::-webkit-scrollbar {
1642
+ display: none; /* Chrome/Safari */
1643
+ }
1644
+
1645
+ /* Tab links */
1646
+ & > a {
1647
+ position: relative;
1648
+ display: inline-flex;
1649
+ align-items: center;
1650
+ gap: var(--spacing-2);
1651
+ padding: var(--spacing-3) var(--spacing-4);
1652
+ font-family: var(--font-family-body);
1653
+ font-size: var(--font-size-base);
1654
+ font-weight: var(--font-weight-medium);
1655
+ color: var(--color-text-secondary);
1656
+ text-decoration: none;
1657
+ white-space: nowrap;
1658
+ border: none;
1659
+ background: transparent;
1660
+ cursor: pointer;
1661
+ transition: color var(--transition-fast);
1662
+ border-bottom: 2px solid transparent;
1663
+ margin-bottom: -2px; /* Overlap the nav border */
1664
+
1665
+ &:hover {
1666
+ color: var(--color-text-primary);
1667
+ background-color: var(--color-surface-hover);
1668
+ }
1669
+
1670
+ &:focus-visible {
1671
+ outline: var(--focus-ring-width, 2px) solid var(--color-primary-500);
1672
+ outline-offset: -2px;
1673
+ border-radius: var(--radius-sm);
1674
+ z-index: 1;
1675
+ }
1676
+
1677
+ /* Active tab */
1678
+ &[aria-current="page"] {
1679
+ color: var(--color-primary-600);
1680
+ font-weight: var(--font-weight-semibold);
1681
+ border-bottom-color: var(--color-primary-600);
1682
+
1683
+ &:hover {
1684
+ color: var(--color-primary-700);
1685
+ border-bottom-color: var(--color-primary-700);
1686
+ background-color: var(--color-primary-50);
1687
+ }
1688
+ }
1689
+ }
1690
+ }
1691
+
1692
+ /* Tab panel */
1693
+ & > pds-tabpanel {
1694
+ display: block;
1695
+ margin-top: var(--spacing-4);
1696
+
1697
+ &[data-tabpanel] {
1698
+ animation: tabFadeIn var(--transition-normal) ease-out;
1699
+ padding: var(--spacing-4) 0;
1700
+
1701
+ &[hidden] {
1702
+ display: none;
1703
+ }
1704
+ }
1705
+ }
1706
+ }
1707
+
1708
+ @keyframes tabFadeIn {
1709
+ from {
1710
+ opacity: 0;
1711
+ transform: translateY(8px);
1712
+ }
1713
+ to {
1714
+ opacity: 1;
1715
+ transform: translateY(0);
1716
+ }
1717
+ }
1718
+
1719
+ /* Mobile responsive */
1720
+ @media (max-width: 639px) {
1721
+ pds-tabstrip > nav {
1722
+ gap: var(--spacing-1);
1723
+ }
1724
+
1725
+ pds-tabstrip > nav > a {
1726
+ padding: var(--spacing-2) var(--spacing-3);
1727
+ font-size: var(--font-size-sm);
1728
+ }
1729
+
1730
+ pds-tabstrip > pds-tabpanel[data-tabpanel] {
1731
+ padding: var(--spacing-3) 0;
1732
+ }
1733
+ }
1734
+
1735
+
1736
+
1737
+ /* Table Styles - Mobile First */
1738
+
1739
+ table {
1740
+ width: 100%;
1741
+ border-collapse: collapse;
1742
+ margin: 0 0 var(--spacing-6) 0;
1743
+ background-color: var(--color-surface-base);
1744
+ border-radius: var(--radius-md);
1745
+ overflow: hidden;
1746
+ font-size: var(--font-size-sm);
1747
+
1748
+ @media (min-width: 640px) {
1749
+ font-size: var(--font-size-base);
1750
+ }
1751
+ }
1752
+
1753
+ .table-responsive {
1754
+ @media (max-width: 639px) {
1755
+ overflow-x: auto;
1756
+ -webkit-overflow-scrolling: touch;
1757
+ margin: 0 0 var(--spacing-6) 0;
1758
+
1759
+ table {
1760
+ min-width: 600px;
1761
+ margin: 0;
1762
+ }
1763
+ }
1764
+ }
1765
+
1766
+ thead {
1767
+ background-color: var(--color-surface-subtle);
1768
+ }
1769
+
1770
+ th {
1771
+ padding: var(--spacing-3) var(--spacing-4);
1772
+ text-align: left;
1773
+ font-weight: var(--font-weight-semibold);
1774
+ color: var(--color-text-primary);
1775
+ border-bottom: 2px solid var(--color-border);
1776
+ }
1777
+
1778
+ td {
1779
+ padding: var(--spacing-3) var(--spacing-4);
1780
+ color: var(--color-text-secondary);
1781
+ border-bottom: 1px solid var(--color-border);
1782
+ }
1783
+
1784
+ tbody {
1785
+ tr {
1786
+ transition: background-color var(--transition-fast);
1787
+
1788
+ &:hover {
1789
+ background-color: var(--color-surface-subtle);
1790
+ }
1791
+
1792
+ &:last-child td {
1793
+ border-bottom: none;
1794
+ }
1795
+ }
1796
+ }
1797
+
1798
+ .table-striped {
1799
+ tbody tr:nth-child(even) {
1800
+ background-color: var(--color-surface-subtle);
1801
+ }
1802
+ }
1803
+
1804
+ .table-bordered {
1805
+ border: 1px solid var(--color-border);
1806
+
1807
+ th, td {
1808
+ border: 1px solid var(--color-border);
1809
+ }
1810
+ }
1811
+
1812
+ .table-compact {
1813
+ th, td {
1814
+ padding: var(--spacing-2) var(--spacing-3);
1815
+ }
1816
+ }
1817
+
1818
+
1819
+
1820
+ /* Card component */
1821
+
1822
+ .card {
1823
+ background: var(--color-surface-base);
1824
+ border-radius: var(--radius-md);
1825
+ padding: var(--spacing-4);
1826
+
1827
+ &-elevated {
1828
+ background: var(--color-surface-elevated);
1829
+ box-shadow: var(--shadow-md);
1830
+ }
1831
+
1832
+ &-outlined,
1833
+ &-basic {
1834
+ background: var(--color-surface-base);
1835
+ border: 1px solid var(--color-border);
1836
+ }
1837
+
1838
+ &-interactive:hover {
1839
+ transform: translateY(-2px);
1840
+ box-shadow: var(--shadow-lg);
1841
+ transition: transform var(--transition-fast), box-shadow var(--transition-fast);
1842
+ }
1843
+ }
1844
+
1845
+ /* Custom Scrollbars */
1846
+
1847
+ ::-webkit-scrollbar {
1848
+ width: 12px;
1849
+ height: 12px;
1850
+
1851
+ &-track {
1852
+ background: transparent;
1853
+ }
1854
+
1855
+ &-thumb {
1856
+ background: var(--color-secondary-300);
1857
+ border-radius: var(--radius-full);
1858
+ border: 3px solid transparent;
1859
+ background-clip: padding-box;
1860
+ transition: background-color var(--transition-fast);
1861
+
1862
+ &:hover {
1863
+ background: var(--color-secondary-400);
1864
+ border: 2px solid transparent;
1865
+ background-clip: padding-box;
1866
+ }
1867
+
1868
+ &:active {
1869
+ background: var(--color-secondary-500);
1870
+ border: 2px solid transparent;
1871
+ background-clip: padding-box;
1872
+ }
1873
+
1874
+ @media (prefers-color-scheme: dark) {
1875
+ background: var(--color-secondary-600);
1876
+
1877
+ &:hover {
1878
+ background: var(--color-secondary-500);
1879
+ }
1880
+
1881
+ &:active {
1882
+ background: var(--color-secondary-400);
1883
+ }
1884
+ }
1885
+ }
1886
+ }
1887
+
1888
+ * {
1889
+ scrollbar-width: thin;
1890
+ scrollbar-color: var(--color-secondary-300) transparent;
1891
+
1892
+ @media (prefers-color-scheme: dark) {
1893
+ scrollbar-color: var(--color-secondary-600) transparent;
1894
+ }
1895
+ }
1896
+
1897
+ /* Hover effect for scrollable containers */
1898
+ *:hover {
1899
+ scrollbar-color: var(--color-secondary-400) transparent;
1900
+ }
1901
+
1902
+ @media (prefers-color-scheme: dark) {
1903
+ *:hover {
1904
+ scrollbar-color: var(--color-secondary-500) transparent;
1905
+ }
1906
+ }
1907
+
1908
+
1909
+
1910
+ /* Alert dark mode adjustments */
1911
+ html[data-theme="dark"] .alert-success {
1912
+ background-color: var(--color-success-50);
1913
+ border-color: var(--color-success-500);
1914
+ color: var(--color-success-900);
1915
+ }
1916
+
1917
+ html[data-theme="dark"] .alert-info {
1918
+ background-color: var(--color-info-50);
1919
+ border-color: var(--color-info-500);
1920
+ color: var(--color-info-900);
1921
+ }
1922
+
1923
+ html[data-theme="dark"] .alert-warning {
1924
+ background-color: var(--color-warning-50);
1925
+ border-color: var(--color-warning-500);
1926
+ color: var(--color-warning-900);
1927
+ }
1928
+
1929
+ html[data-theme="dark"] .alert-danger,
1930
+ html[data-theme="dark"] .alert-error {
1931
+ background-color: var(--color-danger-50);
1932
+ border-color: var(--color-danger-500);
1933
+ color: var(--color-danger-900);
1934
+ }
1935
+
1936
+ /* Dim images in dark mode */
1937
+ html[data-theme="dark"] img,
1938
+ html[data-theme="dark"] video {
1939
+ opacity: 0.8;
1940
+ transition: opacity var(--transition-normal);
1941
+ }
1942
+
1943
+ html[data-theme="dark"] img:hover,
1944
+ html[data-theme="dark"] video:hover {
1945
+ opacity: 1;
1946
+ }
1947
+
1948
+ }
1949
+ `);
1950
+
1951
+ export const componentsCSS = `@layer components {
1952
+
1953
+ /* Semantic HTML Elements (low-specificity via :where()) */
1954
+
1955
+ :where(blockquote) {
1956
+ margin: 0 0 var(--spacing-4) 0;
1957
+ padding: var(--spacing-4) var(--spacing-6);
1958
+ border-left: 4px solid var(--color-primary-500);
1959
+ background-color: var(--color-surface-subtle);
1960
+ border-radius: var(--radius-md);
1961
+ font-style: italic;
1962
+ color: var(--color-text-secondary);
1963
+
1964
+ :where(p):last-child {
1965
+ margin-bottom: 0;
1966
+ }
1967
+
1968
+ :where(cite) {
1969
+ display: block;
1970
+ margin-top: var(--spacing-2);
1971
+ font-size: var(--font-size-sm);
1972
+ font-style: normal;
1973
+ color: var(--color-text-tertiary);
1974
+
1975
+ &::before {
1976
+ content: "— ";
1977
+ }
1978
+ }
1979
+ }
1980
+
1981
+ :where(hr) {
1982
+ margin: var(--spacing-8) 0;
1983
+ border: none;
1984
+ border-top: 1px solid var(--color-border);
1985
+ height: 0;
1986
+ }
1987
+
1988
+ :where(dl) {
1989
+ margin: 0 0 var(--spacing-4) 0;
1990
+ }
1991
+
1992
+ :where(dt) {
1993
+ font-weight: var(--font-weight-semibold);
1994
+ color: var(--color-text-primary);
1995
+ margin-top: var(--spacing-3);
1996
+
1997
+ &:first-child {
1998
+ margin-top: 0;
1999
+ }
2000
+ }
2001
+
2002
+ :where(dd) {
2003
+ margin: var(--spacing-1) 0 var(--spacing-3) var(--spacing-6);
2004
+ color: var(--color-text-secondary);
2005
+ }
2006
+
2007
+ :where(nav), :where(header), :where(footer) {
2008
+ display: block;
2009
+ }
2010
+
2011
+ :where(header), :where(footer) {
2012
+ width: 100%;
2013
+ }
2014
+
2015
+ :where(article), :where(section), :where(aside) {
2016
+ display: block;
2017
+ margin-bottom: var(--spacing-6);
2018
+
2019
+ & > *:last-child {
2020
+ margin-bottom: 0;
2021
+ }
2022
+ }
2023
+
2024
+ :where(mark) {
2025
+ background-color: var(--color-warning-200);
2026
+ color: var(--color-warning-900);
2027
+ padding: 0 var(--spacing-1);
2028
+ border-radius: var(--radius-sm);
2029
+ }
2030
+
2031
+ :where(kbd) {
2032
+ display: inline-block;
2033
+ padding: var(--spacing-1) var(--spacing-2);
2034
+ font-family: var(--font-family-mono);
2035
+ font-size: var(--font-size-sm);
2036
+ color: var(--color-text-primary);
2037
+ background-color: var(--color-surface-elevated);
2038
+ border: 1px solid var(--color-border);
2039
+ border-radius: var(--radius-sm);
2040
+ box-shadow: 0 2px 0 0 var(--color-border);
2041
+ }
2042
+
2043
+ :where(abbr[title]) {
2044
+ text-decoration: underline dotted;
2045
+ cursor: help;
2046
+ text-decoration-thickness: 1px;
2047
+ }
2048
+
2049
+ :where(time) {
2050
+ font-variant-numeric: tabular-nums;
2051
+ }
2052
+
2053
+ :where(address) {
2054
+ font-style: normal;
2055
+ line-height: var(--font-line-height-relaxed);
2056
+ margin: 0 0 var(--spacing-4) 0;
2057
+ }
2058
+
2059
+ :where(details):not(.accordion *) {
2060
+ margin: 0 0 var(--spacing-2) 0;
2061
+ border: 1px solid var(--color-border);
2062
+ border-radius: var(--radius-md);
2063
+ background-color: var(--color-surface-base);
2064
+
2065
+ &[open] :where(summary) {
2066
+ border-bottom: 1px solid var(--color-border);
2067
+ background-color: var(--color-surface-subtle);
2068
+
2069
+ &::after {
2070
+ transform: rotate(270deg);
2071
+ }
2072
+ }
2073
+
2074
+ & > *:not(:where(summary)) {
2075
+ padding: var(--spacing-4);
2076
+ }
2077
+ }
2078
+
2079
+ :where(summary) {
2080
+ padding: var(--spacing-3) var(--spacing-4);
2081
+ cursor: pointer;
2082
+ border-radius: var(--radius-md);
2083
+ font-weight: var(--font-weight-medium);
2084
+ user-select: none;
2085
+ list-style: none;
2086
+ display: flex;
2087
+ align-items: center;
2088
+ justify-content: space-between;
2089
+ transition: background-color var(--transition-fast);
2090
+
2091
+ &::-webkit-details-marker {
2092
+ display: none;
2093
+ }
2094
+
2095
+ &::after {
2096
+ content: "›";
2097
+ display: inline-block;
2098
+ transform: rotate(90deg);
2099
+ transition: transform var(--transition-fast);
2100
+ font-size: var(--font-size-xl);
2101
+ font-weight: var(--font-weight-bold);
2102
+ color: var(--color-text-secondary);
2103
+ }
2104
+
2105
+ &:hover {
2106
+ background-color: var(--color-surface-subtle);
2107
+ }
2108
+ }
2109
+
2110
+ /* Dialog styles moved to #generateDialogStyles() */
2111
+
2112
+
2113
+
2114
+ /* Mobile-First Form Styles - Generated from Design Config */
2115
+ form {
2116
+ margin: 0;
2117
+ width: 100%;
2118
+ }
2119
+
2120
+ fieldset {
2121
+ margin: 0 0 var(--spacing-2) 0;
2122
+ padding: var(--spacing-5);
2123
+ width: 100%;
2124
+ background-color: color-mix(in oklab, var(--color-surface-subtle) 50%, transparent 50%);
2125
+
2126
+ /* Unified styling for radio groups and checkbox groups */
2127
+ &[role="radiogroup"],
2128
+ &[role="group"] {
2129
+ display: flex;
2130
+ flex-direction: column;
2131
+ gap: var(--spacing-2);
2132
+ padding: 0;
2133
+ background-color: transparent;
2134
+
2135
+ label {
2136
+ display: flex;
2137
+ align-items: center;
2138
+ gap: var(--spacing-3);
2139
+ padding: var(--spacing-1) 0;
2140
+ cursor: pointer;
2141
+ min-height: auto;
2142
+ border: none;
2143
+ background: none;
2144
+ font-weight: var(--font-weight-normal);
2145
+ margin-bottom: 0;
2146
+
2147
+ &:hover {
2148
+ color: var(--color-primary-700);
2149
+ }
2150
+ }
2151
+
2152
+ input[type="radio"],
2153
+ input[type="checkbox"] {
2154
+ position: static;
2155
+ opacity: 1;
2156
+ width: var(--spacing-5);
2157
+ height: var(--spacing-5);
2158
+ min-height: var(--spacing-5);
2159
+ margin: 0;
2160
+ cursor: pointer;
2161
+ flex-shrink: 0;
2162
+ accent-color: var(--color-primary-600);
2163
+ appearance: auto;
2164
+ -webkit-appearance: auto;
2165
+ -moz-appearance: auto;
2166
+
2167
+ &:focus {
2168
+ outline: 2px solid var(--color-primary-500);
2169
+ outline-offset: 2px;
2170
+ }
2171
+ }
2172
+ }
2173
+
2174
+ }
2175
+
2176
+
2177
+
2178
+ /* Nested legend scaling: reduce font-size for deeper sub-forms */
2179
+ fieldset > legend { font-size: var(--font-size-lg); }
2180
+ fieldset fieldset > legend { font-size: var(--font-size-base); }
2181
+ fieldset fieldset fieldset > legend { font-size: var(--font-size-sm); }
2182
+
2183
+ .form-container {
2184
+ display: grid;
2185
+ gap: var(--spacing-6);
2186
+ width: 100%;
2187
+ }
2188
+
2189
+ .fields {
2190
+ display: grid;
2191
+ gap: var(--spacing-4);
2192
+ }
2193
+
2194
+ label {
2195
+ display: block;
2196
+ margin-bottom: var(--spacing-3);
2197
+ font-weight: var(--font-weight-medium);
2198
+ color: var(--color-text-primary);
2199
+ font-size: var(--font-size-sm);
2200
+ line-height: var(--font-line-height-normal);
2201
+ }
2202
+
2203
+ [data-label] {
2204
+ display: block;
2205
+ font-weight: var(--font-weight-medium);
2206
+ color: var(--color-text-primary);
2207
+ font-size: var(--font-size-sm);
2208
+ margin-bottom: var(--spacing-2);
2209
+ }
2210
+
2211
+ [data-open]{
2212
+ [data-label]{
2213
+ margin-bottom: 0;
2214
+ }
2215
+ }
2216
+
2217
+ .field-description {
2218
+ font-size: var(--font-size-xs);
2219
+ color: var(--color-text-secondary);
2220
+ margin-top: var(--spacing-1);
2221
+ line-height: var(--font-line-height-relaxed);
2222
+ }
2223
+
2224
+ input, textarea, select {
2225
+ width: 100%;
2226
+ min-height: 40px;
2227
+ padding: calc(var(--spacing-1) * 0.75) var(--spacing-4);
2228
+ border: 1px solid var(--color-border);
2229
+ border-radius: var(--radius-md);
2230
+ font-family: var(--font-family-body);
2231
+ font-size: var(--font-size-base);
2232
+ line-height: var(--font-line-height-normal);
2233
+ background-color: var(--color-input-bg);
2234
+ color: var(--color-text-primary);
2235
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast);
2236
+ touch-action: manipulation;
2237
+ appearance: none;
2238
+ -webkit-appearance: none;
2239
+
2240
+ &:focus {
2241
+ outline: none;
2242
+ border-color: var(--color-primary-500);
2243
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
2244
+ background-color: var(--color-surface-base);
2245
+ }
2246
+
2247
+ &:disabled {
2248
+ background-color: var(--color-input-disabled-bg);
2249
+ color: var(--color-input-disabled-text);
2250
+ border-color: var(--color-border);
2251
+ cursor: not-allowed;
2252
+ opacity: 0.6;
2253
+ }
2254
+
2255
+ &:invalid {
2256
+ border-color: var(--color-danger-500);
2257
+
2258
+ &:focus {
2259
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-danger-500) 30%, transparent);
2260
+ }
2261
+ }
2262
+ }
2263
+
2264
+ input[type="range"] {
2265
+ padding: 0;
2266
+ background: transparent;
2267
+ min-height: auto;
2268
+ }
2269
+
2270
+ /* Make range visually match other inputs */
2271
+ input[type="range"] {
2272
+ -webkit-appearance: none;
2273
+ appearance: none;
2274
+ height: var(--input-min-height, 40px); /* align control height with inputs */
2275
+ width: 100%;
2276
+ }
2277
+
2278
+ /* Track and thumb styling - using CSS nesting to reduce repetition */
2279
+ input[type="range"] {
2280
+ /* WebKit track */
2281
+ &::-webkit-slider-runnable-track {
2282
+ height: var(--range-track-height, 8px);
2283
+ background: var(--color-input-bg);
2284
+ border-radius: var(--radius-full);
2285
+ }
2286
+
2287
+ /* WebKit thumb */
2288
+ &::-webkit-slider-thumb {
2289
+ -webkit-appearance: none;
2290
+ appearance: none;
2291
+ width: var(--range-thumb-size, 28px);
2292
+ height: var(--range-thumb-size, 28px);
2293
+ margin-top: calc((var(--range-track-height, 8px) - var(--range-thumb-size, 28px)) / 2);
2294
+ background: color-mix(in srgb, var(--color-primary-500) 15%, var(--color-surface-base));
2295
+ border-radius: 50%;
2296
+ box-shadow: var(--shadow-sm);
2297
+ cursor: grab;
2298
+ border: 1px solid color-mix(in srgb, var(--color-primary-500) 30%, var(--color-border));
2299
+ }
2300
+
2301
+ /* Mozilla track */
2302
+ &::-moz-range-track {
2303
+ height: var(--range-track-height, 8px);
2304
+ background: var(--color-input-bg);
2305
+ border-radius: var(--radius-full);
2306
+ }
2307
+
2308
+ /* Mozilla thumb */
2309
+ &::-moz-range-thumb {
2310
+ width: var(--range-thumb-size, 28px);
2311
+ height: var(--range-thumb-size, 28px);
2312
+ background: color-mix(in srgb, var(--color-primary-500) 15%, var(--color-surface-base));
2313
+ border-radius: 50%;
2314
+ box-shadow: var(--shadow-sm);
2315
+ border: 1px solid color-mix(in srgb, var(--color-primary-500) 30%, var(--color-border));
2316
+ transform: translateY(calc((var(--range-track-height, 8px) - var(--range-thumb-size, 28px)) / 2));
2317
+ }
2318
+
2319
+ /* Hover and focus states for WebKit */
2320
+ &:hover::-webkit-slider-thumb,
2321
+ &:focus-visible::-webkit-slider-thumb {
2322
+ cursor: grabbing;
2323
+ background: var(--color-primary-500);
2324
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
2325
+ border-color: var(--color-primary-600);
2326
+ }
2327
+
2328
+ /* Active state for WebKit */
2329
+ &:active::-webkit-slider-thumb {
2330
+ background: var(--color-primary-600);
2331
+ }
2332
+
2333
+ /* Hover and focus states for Mozilla */
2334
+ &:hover::-moz-range-thumb,
2335
+ &:focus-visible::-moz-range-thumb {
2336
+ background: var(--color-primary-500);
2337
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
2338
+ border-color: var(--color-primary-600);
2339
+ cursor: grabbing;
2340
+ }
2341
+
2342
+ /* Active state for Mozilla */
2343
+ &:active::-moz-range-thumb {
2344
+ background: var(--color-primary-600);
2345
+ }
2346
+ }
2347
+
2348
+ /* Focus style for container to match input focus */
2349
+ .range-container:focus-within {
2350
+ border-color: var(--color-primary-500);
2351
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary-500) 30%, transparent);
2352
+ }
2353
+
2354
+ input[type="range"]:active::-moz-range-thumb {
2355
+ background: var(--color-primary-600);
2356
+ }
2357
+
2358
+ input[type="color"] {
2359
+ -webkit-appearance: none;
2360
+ padding: 0;
2361
+ width: 3rem;
2362
+ height: 3rem;
2363
+ border-radius: 0.75rem; /* your radius */
2364
+ overflow: hidden; /* important */
2365
+ cursor: pointer;
2366
+
2367
+ /* The wrapper */
2368
+ &::-webkit-color-swatch-wrapper {
2369
+ padding: 0;
2370
+ border-radius: inherit;
2371
+ }
2372
+
2373
+ /* The swatch (the actual color box) */
2374
+ &::-webkit-color-swatch {
2375
+ border: none;
2376
+ border-radius: inherit;
2377
+ }
2378
+ }
2379
+
2380
+ /* Button-style checkbox inputs outside of fieldsets */
2381
+ .checkbox-container input[type="checkbox"] {
2382
+ appearance: none;
2383
+ -webkit-appearance: none;
2384
+ -moz-appearance: none;
2385
+ position: absolute;
2386
+ opacity: 0;
2387
+ width: 0;
2388
+ height: 0;
2389
+ margin: 0;
2390
+ padding: 0;
2391
+ pointer-events: none;
2392
+ }
2393
+
2394
+ label:has(input[type="checkbox"]):not(fieldset label):not(label[data-toggle]),
2395
+ input[type="checkbox"] + label:not(fieldset label):not(label[data-toggle]) {
2396
+ display: inline-flex;
2397
+ align-items: center;
2398
+ justify-content: center;
2399
+ min-height: calc(44px * 0.75);
2400
+ padding: calc(var(--spacing-1) * 0.6) calc(var(--spacing-4) * 0.85);
2401
+ border: 1px solid var(--color-border);
2402
+ border-radius: var(--radius-md);
2403
+ font-family: var(--font-family-body);
2404
+ font-size: var(--font-size-sm);
2405
+ font-weight: var(--font-weight-medium);
2406
+ line-height: 1.2;
2407
+ cursor: pointer;
2408
+ transition: all var(--transition-fast);
2409
+ text-decoration: none;
2410
+ touch-action: manipulation;
2411
+ user-select: none;
2412
+ background-color: transparent;
2413
+ color: var(--color-text-primary);
2414
+ margin: 0;
2415
+ flex: 0 1 auto;
2416
+ white-space: nowrap;
2417
+
2418
+ &:hover {
2419
+ background-color: var(--color-surface-subtle);
2420
+ border-color: var(--color-primary-500);
2421
+ }
2422
+ }
2423
+
2424
+ label:has(input[type="checkbox"]:checked):not(fieldset label):not(label[data-toggle]),
2425
+ input[type="checkbox"]:checked + label:not(fieldset label):not(label[data-toggle]) {
2426
+ background-color: color-mix(in oklab, var(--color-primary-500) 8%, transparent);
2427
+ color: var(--color-primary-700);
2428
+ border-color: var(--color-primary-500);
2429
+ border-width: 2px;
2430
+ font-weight: var(--font-weight-semibold);
2431
+
2432
+ &:hover {
2433
+ background-color: color-mix(in oklab, var(--color-primary-500) 15%, transparent);
2434
+ border-color: var(--color-primary-600);
2435
+ }
2436
+ }
2437
+
2438
+ label:has(input[type="checkbox"]:focus):not(fieldset label):not(label[data-toggle]),
2439
+ input[type="checkbox"]:focus + label:not(fieldset label):not(label[data-toggle]) {
2440
+ outline: none;
2441
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
2442
+ }
2443
+
2444
+ label:has(input[type="checkbox"]:disabled):not(fieldset label):not(label[data-toggle]),
2445
+ input[type="checkbox"]:disabled + label:not(fieldset label):not(label[data-toggle]) {
2446
+ background-color: var(--color-input-disabled-bg);
2447
+ color: var(--color-input-disabled-text);
2448
+ border-color: var(--color-border);
2449
+ cursor: not-allowed;
2450
+ opacity: 0.6;
2451
+ }
2452
+
2453
+ label:has(input[type="checkbox"]:checked:disabled):not(fieldset label):not(label[data-toggle]),
2454
+ input[type="checkbox"]:checked:disabled + label:not(fieldset label):not(label[data-toggle]) {
2455
+ background-color: var(--color-input-disabled-bg);
2456
+ color: var(--color-input-disabled-text);
2457
+ border-color: var(--color-border);
2458
+ }
2459
+
2460
+ /* Keep default checkbox/radio for inputs NOT in special containers */
2461
+ input[type="checkbox"]:not(fieldset input[type="checkbox"]):not(.checkbox-container input[type="checkbox"]),
2462
+ input[type="radio"]:not(fieldset input[type="radio"]) {
2463
+ width: var(--spacing-5);
2464
+ height: var(--spacing-5);
2465
+ min-height: var(--spacing-5);
2466
+ margin-right: var(--spacing-2);
2467
+ cursor: pointer;
2468
+ position: static;
2469
+ opacity: 1;
2470
+ appearance: auto;
2471
+ -webkit-appearance: auto;
2472
+
2473
+ &:disabled {
2474
+ cursor: not-allowed;
2475
+ }
2476
+ }
2477
+
2478
+ /* Button-style radio and checkbox groups with .buttons class */
2479
+ fieldset[role="radiogroup"].buttons,
2480
+ fieldset[role="group"].buttons {
2481
+ flex-direction: row;
2482
+ flex-wrap: wrap;
2483
+ gap: var(--spacing-3);
2484
+
2485
+ input[type="radio"],
2486
+ input[type="checkbox"] {
2487
+ appearance: none;
2488
+ -webkit-appearance: none;
2489
+ -moz-appearance: none;
2490
+ position: absolute;
2491
+ opacity: 0;
2492
+ width: 0;
2493
+ height: 0;
2494
+ margin: 0;
2495
+ padding: 0;
2496
+ pointer-events: none;
2497
+ }
2498
+
2499
+ label {
2500
+ display: inline-flex;
2501
+ align-items: center;
2502
+ justify-content: center;
2503
+ min-height: calc(44px * 0.75);
2504
+ padding: calc(var(--spacing-1) * 0.6) calc(var(--spacing-4) * 0.85);
2505
+ border: 1px solid var(--color-border);
2506
+ border-radius: var(--radius-md);
2507
+ font-family: var(--font-family-body);
2508
+ font-size: var(--font-size-sm);
2509
+ font-weight: var(--font-weight-medium);
2510
+ line-height: 1.2;
2511
+ cursor: pointer;
2512
+ transition: all var(--transition-fast);
2513
+ text-decoration: none;
2514
+ touch-action: manipulation;
2515
+ user-select: none;
2516
+ background-color: transparent;
2517
+ color: var(--color-text-primary);
2518
+ margin: 0;
2519
+ flex: 0 1 auto;
2520
+ white-space: nowrap;
2521
+
2522
+ &:hover {
2523
+ background-color: var(--color-surface-subtle);
2524
+ border-color: var(--color-primary-500);
2525
+ color: var(--color-text-primary);
2526
+ }
2527
+
2528
+ &:has([disabled]){
2529
+ pointer-events: none;
2530
+ }
2531
+ }
2532
+
2533
+ label:has(input[type="radio"]:checked),
2534
+ label:has(input[type="checkbox"]:checked) {
2535
+ background-color: color-mix(in oklab, var(--color-primary-500) 8%, transparent);
2536
+ border-color: var(--color-primary-500);
2537
+ border-width: 2px;
2538
+ font-weight: var(--font-weight-semibold);
2539
+
2540
+ &:hover {
2541
+ background-color: color-mix(in oklab, var(--color-primary-500) 15%, transparent);
2542
+ border-color: var(--color-primary-600);
2543
+ }
2544
+ }
2545
+
2546
+ label:has(input[type="radio"]:focus),
2547
+ label:has(input[type="checkbox"]:focus) {
2548
+ outline: none;
2549
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
2550
+ }
2551
+
2552
+ label:has(input[type="radio"]:disabled),
2553
+ label:has(input[type="checkbox"]:disabled) {
2554
+ background-color: var(--color-input-disabled-bg);
2555
+ color: var(--color-input-disabled-text);
2556
+ border-color: var(--color-border);
2557
+ cursor: not-allowed;
2558
+ opacity: 0.6;
2559
+ }
2560
+
2561
+ label:has(input[type="radio"]:checked:disabled),
2562
+ label:has(input[type="checkbox"]:checked:disabled) {
2563
+ background-color: var(--color-input-disabled-bg);
2564
+ color: var(--color-input-disabled-text);
2565
+ border-color: var(--color-border);
2566
+ }
2567
+ }
2568
+
2569
+ /* Toggle switches - enhanced checkboxes with data-toggle attribute */
2570
+ label[data-toggle] {
2571
+ display: inline-flex;
2572
+ align-items: normal;
2573
+ gap: var(--spacing-3);
2574
+ cursor: pointer;
2575
+ user-select: none;
2576
+ padding: 0;
2577
+ background: transparent;
2578
+ border: none;
2579
+ min-height: auto;
2580
+ font-weight: var(--font-weight-normal);
2581
+
2582
+ /* Hide the original checkbox in toggle switches */
2583
+ input[type="checkbox"] {
2584
+ display: none;
2585
+ }
2586
+
2587
+ /* Toggle switch container */
2588
+ .toggle-switch {
2589
+ position: relative;
2590
+ display: inline-block;
2591
+ width: 44px;
2592
+ height: 24px;
2593
+ background-color: var(--color-gray-300);
2594
+ border-radius: var(--radius-full);
2595
+ transition: background-color 200ms ease;
2596
+ cursor: pointer;
2597
+ flex-shrink: 0;
2598
+ }
2599
+
2600
+ /* Toggle switch knob */
2601
+ .toggle-knob {
2602
+ position: absolute;
2603
+ top: 2px;
2604
+ left: 2px;
2605
+ width: 20px;
2606
+ height: 20px;
2607
+ background-color: #ffffff;
2608
+ border-radius: 50%;
2609
+ transition: left 200ms ease;
2610
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
2611
+ }
2612
+
2613
+ /* Toggle switch when checked - using :has() selector */
2614
+ &:has(input[type="checkbox"]:checked) .toggle-switch {
2615
+ background-color: var(--color-primary-fill);
2616
+ }
2617
+
2618
+
2619
+ /* Toggle knob when checked - always moves to the right */
2620
+ &:has(input[type="checkbox"]:checked) .toggle-knob {
2621
+ left: 22px;
2622
+ }
2623
+
2624
+ /* Focus state for toggle switch */
2625
+ &:has(input[type="checkbox"]:focus) .toggle-switch {
2626
+ outline: 2px solid var(--color-primary-500);
2627
+ outline-offset: 2px;
2628
+ }
2629
+
2630
+ /* Focus visible state when label is focused via keyboard */
2631
+ &:focus-visible .toggle-switch {
2632
+ outline: 2px solid var(--color-primary-500);
2633
+ outline-offset: 2px;
2634
+ }
2635
+
2636
+ /* Remove default outline on label itself */
2637
+ &:focus {
2638
+ outline: none;
2639
+ }
2640
+
2641
+ /* Disabled state */
2642
+ &:has(input[type="checkbox"]:disabled) {
2643
+ cursor: not-allowed;
2644
+ opacity: 0.6;
2645
+
2646
+ .toggle-switch {
2647
+ opacity: 0.5;
2648
+ cursor: not-allowed;
2649
+ }
2650
+ }
2651
+ }
2652
+
2653
+ input[type="file"] {
2654
+ padding: var(--spacing-2) var(--spacing-4);
2655
+ cursor: pointer;
2656
+ }
2657
+
2658
+ /* Textareas */
2659
+ textarea {
2660
+ min-height: calc(var(--spacing-4) * 5);
2661
+ padding: var(--spacing-3) var(--spacing-4);
2662
+ resize: vertical;
2663
+ line-height: var(--font-line-height-relaxed);
2664
+ }
2665
+
2666
+ /* Select dropdowns */
2667
+ select {
2668
+ cursor: pointer;
2669
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
2670
+ background-position: right var(--spacing-2) center;
2671
+ background-repeat: no-repeat;
2672
+ background-size: 1.5em 1.5em;
2673
+ padding-right: var(--spacing-8);
2674
+ }
2675
+
2676
+ /* Button styling */
2677
+ button, .btn, input[type="submit"], input[type="button"], input[type="reset"] {
2678
+ display: inline-flex;
2679
+ gap: var(--spacing-1);
2680
+ align-items: center;
2681
+ justify-content: center;
2682
+ min-height: 44px;
2683
+ padding: calc(var(--spacing-1) * 1) var(--spacing-6);
2684
+ border: 1px solid transparent;
2685
+ border-radius: var(--radius-md);
2686
+ font-family: var(--font-family-body);
2687
+ font-size: var(--font-size-base);
2688
+ font-weight: var(--font-weight-medium);
2689
+ line-height: 1;
2690
+ cursor: pointer;
2691
+ transition: all var(--transition-fast);
2692
+ text-decoration: none;
2693
+ touch-action: manipulation;
2694
+ user-select: none;
2695
+ background-color: var(--color-surface-base);
2696
+ color: var(--color-text-primary);
2697
+ border-color: var(--color-border);
2698
+
2699
+ /* Only apply generic hover to non-variant buttons */
2700
+ &:hover:not(.btn-primary):not(.btn-secondary):not(.btn-outline) {
2701
+ background-color: var(--color-surface-elevated);
2702
+ }
2703
+
2704
+ &:focus {
2705
+ outline: none;
2706
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
2707
+ }
2708
+
2709
+ &:disabled {
2710
+ background-color: var(--color-input-disabled-bg);
2711
+ color: var(--color-input-disabled-text);
2712
+ border-color: var(--color-input-disabled-bg);
2713
+ cursor: not-allowed;
2714
+ opacity: 0.6;
2715
+ }
2716
+ }
2717
+
2718
+ .btn-primary {
2719
+ background-color: var(--color-primary-fill);
2720
+ color: white;
2721
+ border-color: var(--color-primary-fill);
2722
+
2723
+ &:hover {
2724
+ background-color: color-mix(in oklab, var(--color-primary-fill) 90%, black 10%);
2725
+ border-color: color-mix(in oklab, var(--color-primary-fill) 90%, black 10%);
2726
+ color: white;
2727
+ }
2728
+
2729
+ &:active {
2730
+ background-color: color-mix(in oklab, var(--color-primary-fill) 80%, black 20%);
2731
+ border-color: color-mix(in oklab, var(--color-primary-fill) 80%, black 20%);
2732
+ color: white;
2733
+ }
2734
+
2735
+ &:focus {
2736
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
2737
+ }
2738
+
2739
+ &:disabled {
2740
+ background-color: var(--color-input-disabled-bg);
2741
+ color: var(--color-input-disabled-text);
2742
+ border-color: var(--color-input-disabled-bg);
2743
+ }
2744
+ }
2745
+
2746
+ .btn-secondary {
2747
+ background-color: var(--color-surface-base);
2748
+ color: var(--color-text-primary);
2749
+ border-color: var(--color-border);
2750
+
2751
+ &:hover {
2752
+ background-color: var(--color-surface-elevated);
2753
+ }
2754
+ }
2755
+
2756
+ .btn-outline {
2757
+ background-color: transparent;
2758
+ color: var(--color-primary-500);
2759
+ border-color: var(--color-primary-500);
2760
+
2761
+ &:hover {
2762
+ background-color: var(--color-primary-500);
2763
+ color: var(--color-primary-contrast, #ffffff);
2764
+ border-color: var(--color-primary-500);
2765
+
2766
+ pds-icon {
2767
+ color: var(--color-primary-contrast, #ffffff);
2768
+ }
2769
+ }
2770
+
2771
+ &:active {
2772
+ background-color: color-mix(in oklab, var(--color-primary-500) 80%, black 20%);
2773
+ border-color: color-mix(in oklab, var(--color-primary-500) 80%, black 20%);
2774
+ color: var(--color-primary-contrast, #ffffff);
2775
+
2776
+ pds-icon {
2777
+ color: var(--color-primary-contrast, #ffffff);
2778
+ }
2779
+ }
2780
+
2781
+ &:disabled {
2782
+ background-color: transparent;
2783
+ color: var(--color-input-disabled-text);
2784
+ border-color: var(--color-input-disabled-bg);
2785
+ }
2786
+ }
2787
+
2788
+ .btn-sm {
2789
+ padding: var(--spacing-2) var(--spacing-4);
2790
+ font-size: var(--font-size-sm);
2791
+ min-height: calc(44px * 0.8);
2792
+ }
2793
+
2794
+ .btn-xs {
2795
+ padding: var(--spacing-1) var(--spacing-2);
2796
+ font-size: var(--font-size-xs);
2797
+ min-height: calc(44px * 0.6);
2798
+ }
2799
+
2800
+
2801
+ .btn-lg {
2802
+ padding: var(--spacing-4) var(--spacing-8);
2803
+ font-size: var(--font-size-lg);
2804
+ min-height: calc(44px * 1.2);
2805
+ }
2806
+
2807
+ /* Working/loading state for buttons */
2808
+ button.btn-working,
2809
+ a.btn-working {
2810
+ cursor: wait;
2811
+ pointer-events: none;
2812
+ opacity: 0.6;
2813
+
2814
+ pds-icon:first-child {
2815
+ animation: pds-spin 0.8s linear infinite;
2816
+ }
2817
+ }
2818
+
2819
+ @keyframes pds-spin {
2820
+ to { transform: rotate(360deg); }
2821
+ }
2822
+
2823
+ /* Skeleton loading animation */
2824
+ .skeleton {
2825
+ background: linear-gradient(
2826
+ 90deg,
2827
+ color-mix(in oklab, var(--color-surface-base) 92%, var(--color-text-primary) 8%) 0%,
2828
+ color-mix(in oklab, var(--color-surface-base) 85%, var(--color-text-primary) 15%) 50%,
2829
+ color-mix(in oklab, var(--color-surface-base) 92%, var(--color-text-primary) 8%) 100%
2830
+ );
2831
+ background-size: 200% 100%;
2832
+ animation: pds-skeleton 1.5s ease-in-out infinite;
2833
+ border-radius: var(--radius-sm);
2834
+
2835
+ &::before {
2836
+ content: '\\00a0';
2837
+ }
2838
+ }
2839
+
2840
+ @keyframes pds-skeleton {
2841
+ 0% { background-position: 200% 0; }
2842
+ 100% { background-position: -200% 0; }
2843
+ }
2844
+
2845
+ /* Form utility classes */
2846
+ .range-container {
2847
+ display: flex;
2848
+ align-items: center;
2849
+ gap: var(--spacing-3);
2850
+ width: 100%;
2851
+ background: var(--color-input-bg);
2852
+ border: 1px solid var(--color-border);
2853
+ border-radius: var(--radius-md);
2854
+ min-height: var(--input-min-height, 40px);
2855
+ position: relative;
2856
+
2857
+ input[type="range"] {
2858
+ border: none;
2859
+ }
2860
+ }
2861
+
2862
+ .range-bubble {
2863
+ position: absolute;
2864
+ top: calc(-1 * (var(--range-thumb-size, 28px) + var(--spacing-2)));
2865
+ transform: translateX(-50%);
2866
+ min-width: calc(var(--range-thumb-size, 28px) * 0.8);
2867
+ padding: var(--spacing-1) var(--spacing-2);
2868
+ border-radius: var(--radius-md);
2869
+ background: var(--color-surface-base);
2870
+ color: var(--color-text-primary);
2871
+ text-align: center;
2872
+ font-size: var(--font-size-sm);
2873
+ box-shadow: var(--shadow-md);
2874
+ opacity: 0;
2875
+ pointer-events: none;
2876
+ transition: opacity 150ms ease, transform 150ms ease;
2877
+
2878
+ &.visible {
2879
+ opacity: 1;
2880
+ }
2881
+ }
2882
+
2883
+ /* Anchor bubble to the thumb position using left (set by enhancer)
2884
+ and center with translateX(-50%). */
2885
+
2886
+ /* Array field styling */
2887
+ .array-list {
2888
+ display: flex;
2889
+ flex-direction: column;
2890
+ gap: var(--spacing-4);
2891
+ margin-bottom: var(--spacing-4);
2892
+ }
2893
+
2894
+ .array-item {
2895
+ position: relative;
2896
+ padding: var(--spacing-4);
2897
+ border: 1px solid var(--color-border);
2898
+ border-radius: var(--radius-md);
2899
+ background-color: var(--color-surface-base);
2900
+
2901
+ fieldset {
2902
+ background-color: transparent;
2903
+ margin-bottom: var(--spacing-3);
2904
+
2905
+ &:last-of-type {
2906
+ margin-bottom: 0;
2907
+ }
2908
+ }
2909
+
2910
+ .array-controls {
2911
+ padding-top: var(--spacing-3);
2912
+ border-top: 1px solid var(--color-border);
2913
+ margin-top: var(--spacing-4);
2914
+ }
2915
+ }
2916
+
2917
+ .array-controls {
2918
+ display: flex;
2919
+ gap: var(--spacing-2);
2920
+ margin-top: var(--spacing-3);
2921
+ flex-wrap: wrap;
2922
+
2923
+ button {
2924
+ padding: var(--spacing-2) var(--spacing-3);
2925
+ font-size: var(--font-size-sm);
2926
+ min-height: auto;
2927
+ }
2928
+ }
2929
+
2930
+ .range-value {
2931
+ min-width: var(--spacing-16);
2932
+ text-align: right;
2933
+ font-weight: var(--font-weight-medium);
2934
+ font-size: var(--font-size-sm);
2935
+ color: var(--color-text-primary);
2936
+ }
2937
+
2938
+ .checkbox-container {
2939
+ display: flex;
2940
+ flex-direction: row;
2941
+ align-items: center;
2942
+ gap: var(--spacing-2);
2943
+ flex-wrap: wrap;
2944
+
2945
+ input[type="checkbox"],
2946
+ input[type="radio"] {
2947
+ position: absolute;
2948
+ opacity: 0;
2949
+ }
2950
+ }
2951
+
2952
+
2953
+
2954
+ /* Alert/Notification Styles */
2955
+
2956
+ /* Alias: .semantic-message shares alert base styles */
2957
+ .alert, .semantic-message {
2958
+ padding: var(--spacing-4);
2959
+ border-radius: var(--radius-md);
2960
+ margin: 0 0 var(--spacing-4) 0;
2961
+ border-left: 4px solid;
2962
+ display: flex;
2963
+ align-items: flex-start;
2964
+ gap: var(--spacing-3);
2965
+ font-size: var(--font-size-sm);
2966
+ line-height: var(--font-line-height-relaxed);
2967
+
2968
+ & > *:last-child {
2969
+ margin-bottom: 0;
2970
+ }
2971
+ }
2972
+ /* Variants: success/info/warning/danger mapped to tokens */
2973
+ .alert-success, .semantic-message.success {
2974
+ background-color: var(--color-success-50);
2975
+ border-color: var(--color-success-600);
2976
+ color: var(--color-success-900);
2977
+ }
2978
+ .alert-info, .semantic-message.info {
2979
+ background-color: var(--color-info-50);
2980
+ border-color: var(--color-info-600);
2981
+ color: var(--color-info-900);
2982
+ }
2983
+ .alert-warning, .semantic-message.warning {
2984
+ background-color: var(--color-warning-50);
2985
+ border-color: var(--color-warning-600);
2986
+ color: var(--color-warning-900);
2987
+ }
2988
+ .alert-danger,
2989
+ .alert-error,
2990
+ .semantic-message.danger {
2991
+ background-color: var(--color-danger-50);
2992
+ border-color: var(--color-danger-600);
2993
+ color: var(--color-danger-900);
2994
+ }
2995
+
2996
+ /* Semantic-message content defaults */
2997
+ .semantic-message strong { display: block; }
2998
+ .semantic-message p { margin: 0; font-size: var(--font-size-sm); }
2999
+
3000
+ .alert-title {
3001
+ font-weight: var(--font-weight-semibold);
3002
+ margin: 0 0 var(--spacing-2) 0;
3003
+ font-size: var(--font-size-base);
3004
+ }
3005
+
3006
+ .alert-icon {
3007
+ flex-shrink: 0;
3008
+ display: flex;
3009
+ align-items: center;
3010
+ justify-content: center;
3011
+
3012
+ pds-icon {
3013
+ flex-shrink: 0;
3014
+ }
3015
+ }
3016
+
3017
+ .alert-dismissible {
3018
+ padding-right: var(--spacing-12);
3019
+ position: relative;
3020
+ }
3021
+
3022
+ .alert-close {
3023
+ position: absolute;
3024
+ top: var(--spacing-3);
3025
+ right: var(--spacing-3);
3026
+ background: none;
3027
+ border: none;
3028
+ font-size: var(--font-size-xl);
3029
+ line-height: 1;
3030
+ opacity: 0.6;
3031
+ cursor: pointer;
3032
+ padding: var(--spacing-1);
3033
+ transition: opacity var(--transition-fast);
3034
+
3035
+ &:hover {
3036
+ opacity: 1;
3037
+ }
3038
+ }
3039
+
3040
+
3041
+
3042
+ /* Badge/Pill Styles */
3043
+
3044
+ .badge {
3045
+ display: inline-flex;
3046
+ align-items: center;
3047
+ justify-content: center;
3048
+ padding: var(--spacing-1) var(--spacing-2);
3049
+ font-size: var(--font-size-xs);
3050
+ font-weight: var(--font-weight-semibold);
3051
+ line-height: 1;
3052
+ border-radius: var(--radius-full);
3053
+ white-space: nowrap;
3054
+ vertical-align: middle;
3055
+ background-color: var(--color-gray-200);
3056
+ color: var(--color-gray-800);
3057
+ border-radius: var(--radius-full);
3058
+ }
3059
+
3060
+ .badge-primary {
3061
+ background-color: var(--color-primary-600);
3062
+ color: white;
3063
+ }
3064
+
3065
+ .badge-secondary {
3066
+ background-color: var(--color-secondary-600);
3067
+ color: white;
3068
+ }
3069
+
3070
+ .badge-success {
3071
+ background-color: var(--color-success-600);
3072
+ color: white;
3073
+ }
3074
+
3075
+ .badge-info {
3076
+ background-color: var(--color-info-600);
3077
+ color: white;
3078
+ }
3079
+
3080
+ .badge-warning {
3081
+ background-color: var(--color-warning-600);
3082
+ color: white;
3083
+ }
3084
+
3085
+ .badge-danger {
3086
+ background-color: var(--color-danger-600);
3087
+ color: white;
3088
+ }
3089
+
3090
+ .badge-outline {
3091
+ background-color: transparent;
3092
+ border: 1px solid currentColor;
3093
+
3094
+ &.badge-primary {
3095
+ color: var(--color-text-primary);
3096
+ }
3097
+
3098
+ &.badge-secondary {
3099
+ color: var(--color-secondary-600);
3100
+ }
3101
+
3102
+ &.badge-success {
3103
+ color: var(--color-success-600);
3104
+ }
3105
+
3106
+ &.badge-info {
3107
+ color: var(--color-info-600);
3108
+ }
3109
+
3110
+ &.badge-warning {
3111
+ color: var(--color-warning-600);
3112
+ }
3113
+
3114
+ &.badge-danger {
3115
+ color: var(--color-danger-600);
3116
+ }
3117
+ }
3118
+
3119
+ .badge-sm {
3120
+ padding: 2px var(--spacing-1);
3121
+ font-size: 10px;
3122
+ }
3123
+
3124
+ .badge-lg {
3125
+ padding: var(--spacing-2) var(--spacing-3);
3126
+ font-size: var(--font-size-sm);
3127
+ }
3128
+
3129
+ .pill {
3130
+ padding: var(--spacing-1) var(--spacing-3);
3131
+ border-radius: var(--radius-full);
3132
+ }
3133
+
3134
+
3135
+
3136
+ /* ============================================================================
3137
+ Dialog Primitive
3138
+ Native <dialog> element with PDS integration
3139
+ ============================================================================ */
3140
+
3141
+ /* Dialog base styles */
3142
+ dialog {
3143
+ position: fixed;
3144
+ inset: 0;
3145
+ max-width: min(600px, calc(100vw - var(--spacing-8)));
3146
+ max-height: calc(100vh - var(--spacing-8));
3147
+ margin: auto;
3148
+ padding: 0;
3149
+ border: none;
3150
+ border-radius: var(--radius-lg);
3151
+
3152
+ /* Surface styling - elevated overlay */
3153
+ background-color: var(--surface-overlay-bg);
3154
+ color: var(--surface-overlay-text);
3155
+ box-shadow: 0 8px 32px var(--surface-overlay-shadow);
3156
+
3157
+ /* Smooth transitions */
3158
+ opacity: 0;
3159
+ scale: 0.95;
3160
+ transition:
3161
+ opacity 0.2s ease,
3162
+ scale 0.2s ease,
3163
+ overlay 0.2s ease allow-discrete,
3164
+ display 0.2s ease allow-discrete;
3165
+
3166
+ /* Overflow handling */
3167
+ overflow: hidden;
3168
+ }
3169
+
3170
+ /* Open state */
3171
+ dialog[open] {
3172
+ opacity: 1;
3173
+ scale: 1;
3174
+ }
3175
+
3176
+ /* Starting style for smooth open animation */
3177
+ @starting-style {
3178
+ dialog[open] {
3179
+ opacity: 0;
3180
+ scale: 0.95;
3181
+ }
3182
+ }
3183
+
3184
+ /* Backdrop styling */
3185
+ dialog::backdrop {
3186
+ background: var(--backdrop-bg);
3187
+ backdrop-filter: var(--backdrop-filter);
3188
+ opacity: 0;
3189
+ transition:
3190
+ opacity 0.2s ease,
3191
+ overlay 0.2s ease allow-discrete,
3192
+ display 0.2s ease allow-discrete;
3193
+ }
3194
+
3195
+ dialog[open]::backdrop {
3196
+ opacity: var(--backdrop-opacity, 1);
3197
+ }
3198
+
3199
+ @starting-style {
3200
+ dialog[open]::backdrop {
3201
+ opacity: 0;
3202
+ }
3203
+ }
3204
+
3205
+ /* Form structure - use flexbox instead of contents */
3206
+ dialog form {
3207
+ display: flex;
3208
+ flex-direction: column;
3209
+ height: 100%;
3210
+ margin: 0;
3211
+ }
3212
+
3213
+ /* Dialog fields - to open pds-jsonform subforms */
3214
+ .dialog-field {
3215
+ margin-top: var(--spacing-3);
3216
+ }
3217
+
3218
+ /* Dialog header */
3219
+ dialog {
3220
+ header,
3221
+ form > header {
3222
+ display: flex;
3223
+ align-items: center;
3224
+ justify-content: space-between;
3225
+ gap: var(--spacing-4);
3226
+ padding: var(--spacing-6);
3227
+ border-bottom: 1px solid var(--surface-overlay-border);
3228
+ flex-shrink: 0;
3229
+
3230
+ h2,
3231
+ h3 {
3232
+ margin: 0;
3233
+ font-size: var(--font-size-lg);
3234
+ font-weight: var(--font-weight-semibold);
3235
+ color: var(--surface-overlay-text);
3236
+ flex: 1;
3237
+ }
3238
+
3239
+ /* Close button in header */
3240
+ button[value="cancel"],
3241
+ .dialog-close {
3242
+ background: none;
3243
+ border: none;
3244
+ padding: var(--spacing-2);
3245
+ border-radius: var(--radius-sm);
3246
+ cursor: pointer;
3247
+ color: var(--surface-overlay-icon);
3248
+ transition: background-color var(--transition-fast);
3249
+ display: inline-flex;
3250
+ align-items: center;
3251
+ justify-content: center;
3252
+
3253
+ &:hover {
3254
+ background-color: var(--color-surface-subtle);
3255
+ }
3256
+
3257
+ &:focus-visible {
3258
+ outline: 2px solid var(--color-focus-ring);
3259
+ outline-offset: 2px;
3260
+ }
3261
+ }
3262
+ }
3263
+
3264
+ /* Dialog body - scrollable content */
3265
+ article,
3266
+ form > article,
3267
+ .dialog-body {
3268
+ flex: 1;
3269
+ padding: var(--spacing-6);
3270
+ overflow-y: auto;
3271
+ overflow-x: hidden;
3272
+ }
3273
+
3274
+ /* Dialog footer - actions */
3275
+ footer,
3276
+ form > footer {
3277
+ display: flex;
3278
+ flex-direction: row;
3279
+ gap: var(--spacing-3);
3280
+ justify-content: flex-end;
3281
+ align-items: center;
3282
+ padding: var(--spacing-6);
3283
+ border-top: 1px solid var(--surface-overlay-border);
3284
+ flex-shrink: 0;
3285
+ }
3286
+ }
3287
+
3288
+ /* Dialog size modifiers */
3289
+ dialog.dialog-sm {
3290
+ max-width: min(400px, calc(100vw - var(--spacing-8)));
3291
+ }
3292
+
3293
+ dialog.dialog-lg {
3294
+ max-width: min(800px, calc(100vw - var(--spacing-8)));
3295
+ }
3296
+
3297
+ dialog.dialog-xl {
3298
+ max-width: min(1200px, calc(100vw - var(--spacing-8)));
3299
+ }
3300
+
3301
+ dialog.dialog-full {
3302
+ max-width: calc(100vw - var(--spacing-8));
3303
+ max-height: calc(100vh - var(--spacing-8));
3304
+ }
3305
+
3306
+ /* Mobile responsiveness */
3307
+ @media (max-width: 639px) {
3308
+ dialog {
3309
+ max-width: 100vw;
3310
+ max-height: 100vh;
3311
+ border-radius: 0;
3312
+ top: 50%;
3313
+ transform: translateY(-50%);
3314
+ margin: 0;
3315
+ }
3316
+
3317
+ dialog header,
3318
+ dialog form > header,
3319
+ dialog article,
3320
+ dialog form > article,
3321
+ dialog footer,
3322
+ dialog form > footer {
3323
+ padding: var(--spacing-4);
3324
+ }
3325
+ }
3326
+
3327
+ /* Reduced motion support */
3328
+ @media (prefers-reduced-motion: reduce) {
3329
+ dialog,
3330
+ dialog::backdrop {
3331
+ transition-duration: 0.01s !important;
3332
+ }
3333
+ }
3334
+
3335
+
3336
+
3337
+ /* Accordion (details/summary) */
3338
+
3339
+ .accordion {
3340
+ --_acc-radius: var(--radius-md);
3341
+ --_acc-border: 1px solid var(--color-border);
3342
+ --_acc-bg: var(--color-surface-base);
3343
+
3344
+ details {
3345
+ border: var(--_acc-border);
3346
+ border-radius: var(--_acc-radius);
3347
+ background: var(--_acc-bg);
3348
+ margin: 0 0 var(--spacing-3) 0;
3349
+
3350
+ &[open] {
3351
+ & > summary::after {
3352
+ transform: rotate(45deg);
3353
+ }
3354
+
3355
+ &::details-content {
3356
+ block-size: auto;
3357
+ }
3358
+ }
3359
+
3360
+ /* Modern approach: animate block-size with ::details-content */
3361
+ &::details-content {
3362
+ block-size: 0;
3363
+ overflow: hidden;
3364
+ transition: block-size var(--transition-normal) ease, content-visibility var(--transition-normal);
3365
+ transition-behavior: allow-discrete;
3366
+ }
3367
+
3368
+ /* Content padding (works for both approaches) */
3369
+ & > :not(summary) > * {
3370
+ padding-inline: var(--spacing-4);
3371
+ padding-block: var(--spacing-3);
3372
+ }
3373
+ }
3374
+
3375
+ summary {
3376
+ cursor: pointer;
3377
+ padding: var(--spacing-3) var(--spacing-4);
3378
+ list-style: none;
3379
+ outline: none;
3380
+ display: flex;
3381
+ align-items: center;
3382
+ gap: var(--spacing-2);
3383
+
3384
+ &::-webkit-details-marker {
3385
+ display: none;
3386
+ }
3387
+
3388
+ /* Chevron indicator */
3389
+ &::after {
3390
+ content: "";
3391
+ margin-inline-start: auto;
3392
+ inline-size: 0.7em;
3393
+ block-size: 0.7em;
3394
+ border-inline-end: 2px solid currentColor;
3395
+ border-block-end: 2px solid currentColor;
3396
+ transform: rotate(-45deg);
3397
+ transition: transform var(--transition-normal);
3398
+ }
3399
+ }
3400
+ }
3401
+
3402
+ /* Fallback: grid trick for browsers without ::details-content support */
3403
+ @supports not selector(::details-content) {
3404
+ .accordion details {
3405
+ & > :not(summary) {
3406
+ display: grid;
3407
+ grid-template-rows: 0fr;
3408
+ transition: grid-template-rows var(--transition-normal) ease;
3409
+ overflow: hidden;
3410
+
3411
+ & > * {
3412
+ min-block-size: 0;
3413
+ }
3414
+ }
3415
+
3416
+ &[open] > :not(summary) {
3417
+ grid-template-rows: 1fr;
3418
+ }
3419
+ }
3420
+ }
3421
+
3422
+
3423
+ /* Dropdown Component */
3424
+
3425
+ /* Basic dropdown host */
3426
+ nav[data-dropdown] {
3427
+ position: relative;
3428
+ display: inline-block;
3429
+ padding: 0;
3430
+
3431
+ menu {
3432
+ position: absolute;
3433
+ list-style: none;
3434
+ padding: var(--spacing-2);
3435
+ margin: 0;
3436
+ background: var(--color-surface-overlay);
3437
+ border: 1px solid var(--color-border);
3438
+ border-radius: var(--radius-md);
3439
+ box-shadow: var(--shadow-lg);
3440
+ top: 100%;
3441
+ bottom: auto;
3442
+ left: 0;
3443
+ right: auto;
3444
+ margin-top: var(--spacing-2);
3445
+ --dropdown-transition-duration: var(--transition-fast, 160ms);
3446
+ min-width: max(100%, var(--dropdown-min-width, 12rem));
3447
+ width: max-content;
3448
+ opacity: 0;
3449
+ scale: 0.95;
3450
+ visibility: hidden;
3451
+ display: none;
3452
+ pointer-events: none;
3453
+ transform-origin: top center;
3454
+ z-index: var(--z-dropdown, 1050);
3455
+ max-height: min(60vh, 24rem);
3456
+ overflow-y: auto;
3457
+ transition:
3458
+ opacity var(--dropdown-transition-duration) ease,
3459
+ scale var(--dropdown-transition-duration) ease,
3460
+ visibility 0s linear var(--dropdown-transition-duration),
3461
+ display 0s linear var(--dropdown-transition-duration);
3462
+ transition-behavior: allow-discrete;
3463
+ }
3464
+
3465
+ menu[aria-hidden="false"] {
3466
+ display: block;
3467
+ opacity: 1;
3468
+ scale: 1;
3469
+ visibility: visible;
3470
+ pointer-events: auto;
3471
+ transition:
3472
+ opacity var(--dropdown-transition-duration) ease,
3473
+ scale var(--dropdown-transition-duration) ease,
3474
+ visibility 0s linear 0s,
3475
+ display 0s linear 0s;
3476
+ }
3477
+
3478
+ li {
3479
+ padding: var(--spacing-1) 0;
3480
+
3481
+ & + li {
3482
+ border-top: 1px solid var(--color-border);
3483
+ margin-top: var(--spacing-2);
3484
+ }
3485
+
3486
+ &:has(> hr) {
3487
+ border-top: none;
3488
+ margin-top: 0;
3489
+ padding: 0;
3490
+
3491
+ & + li {
3492
+ border-top: none;
3493
+ margin-top: 0;
3494
+ }
3495
+ }
3496
+
3497
+ & > hr {
3498
+ border: none;
3499
+ border-top: 3px solid var(--color-border);
3500
+ margin: var(--spacing-2) 0;
3501
+ }
3502
+ }
3503
+
3504
+ a {
3505
+ display: flex;
3506
+ color: var(--color-text-primary);
3507
+ text-decoration: none;
3508
+ align-items: center;
3509
+ gap: var(--spacing-2);
3510
+
3511
+ &.danger {
3512
+ color: var(--color-danger-600);
3513
+ }
3514
+ }
3515
+
3516
+ &.align-right,
3517
+ &[data-align="right"],
3518
+ &[data-align="end"],
3519
+ &[data-dropdown-align="right"],
3520
+ &[data-dropdown-align="end"] {
3521
+ menu {
3522
+ left: auto;
3523
+ right: 0;
3524
+ }
3525
+ }
3526
+
3527
+ &[data-mode="up"],
3528
+ &[data-dropdown-direction="up"] {
3529
+ menu {
3530
+ top: auto;
3531
+ bottom: 100%;
3532
+ margin-top: 0;
3533
+ margin-bottom: var(--spacing-2);
3534
+ transform-origin: bottom center;
3535
+ }
3536
+ }
3537
+
3538
+ &[data-mode="down"],
3539
+ &[data-dropdown-direction="down"] {
3540
+ menu {
3541
+ top: 100%;
3542
+ bottom: auto;
3543
+ margin-top: var(--spacing-2);
3544
+ margin-bottom: 0;
3545
+ transform-origin: top center;
3546
+ }
3547
+ }
3548
+
3549
+ &[data-mode="auto"] menu {
3550
+ top: 100%;
3551
+ bottom: auto;
3552
+ }
3553
+
3554
+ @media (prefers-reduced-motion: reduce) {
3555
+ menu {
3556
+ transition-duration: 0.01s !important;
3557
+ }
3558
+ }
3559
+ }
3560
+
3561
+ @starting-style {
3562
+ nav[data-dropdown] menu[aria-hidden="false"] {
3563
+ opacity: 0;
3564
+ scale: 0.95;
3565
+ }
3566
+ }
3567
+
3568
+
3569
+ /* Tab Strip Component */
3570
+
3571
+ /* Tab navigation */
3572
+
3573
+ pds-tabstrip {
3574
+ margin-top: var(--spacing-6);
3575
+
3576
+ & > nav {
3577
+ display: flex;
3578
+ gap: var(--spacing-1);
3579
+ border-bottom: 2px solid var(--color-border);
3580
+ margin-bottom: var(--spacing-6);
3581
+ position: relative;
3582
+ overflow-x: auto;
3583
+ overflow-y: hidden;
3584
+ scrollbar-width: none; /* Firefox */
3585
+ -ms-overflow-style: none; /* IE/Edge */
3586
+
3587
+ &::-webkit-scrollbar {
3588
+ display: none; /* Chrome/Safari */
3589
+ }
3590
+
3591
+ /* Tab links */
3592
+ & > a {
3593
+ position: relative;
3594
+ display: inline-flex;
3595
+ align-items: center;
3596
+ gap: var(--spacing-2);
3597
+ padding: var(--spacing-3) var(--spacing-4);
3598
+ font-family: var(--font-family-body);
3599
+ font-size: var(--font-size-base);
3600
+ font-weight: var(--font-weight-medium);
3601
+ color: var(--color-text-secondary);
3602
+ text-decoration: none;
3603
+ white-space: nowrap;
3604
+ border: none;
3605
+ background: transparent;
3606
+ cursor: pointer;
3607
+ transition: color var(--transition-fast);
3608
+ border-bottom: 2px solid transparent;
3609
+ margin-bottom: -2px; /* Overlap the nav border */
3610
+
3611
+ &:hover {
3612
+ color: var(--color-text-primary);
3613
+ background-color: var(--color-surface-hover);
3614
+ }
3615
+
3616
+ &:focus-visible {
3617
+ outline: var(--focus-ring-width, 2px) solid var(--color-primary-500);
3618
+ outline-offset: -2px;
3619
+ border-radius: var(--radius-sm);
3620
+ z-index: 1;
3621
+ }
3622
+
3623
+ /* Active tab */
3624
+ &[aria-current="page"] {
3625
+ color: var(--color-primary-600);
3626
+ font-weight: var(--font-weight-semibold);
3627
+ border-bottom-color: var(--color-primary-600);
3628
+
3629
+ &:hover {
3630
+ color: var(--color-primary-700);
3631
+ border-bottom-color: var(--color-primary-700);
3632
+ background-color: var(--color-primary-50);
3633
+ }
3634
+ }
3635
+ }
3636
+ }
3637
+
3638
+ /* Tab panel */
3639
+ & > pds-tabpanel {
3640
+ display: block;
3641
+ margin-top: var(--spacing-4);
3642
+
3643
+ &[data-tabpanel] {
3644
+ animation: tabFadeIn var(--transition-normal) ease-out;
3645
+ padding: var(--spacing-4) 0;
3646
+
3647
+ &[hidden] {
3648
+ display: none;
3649
+ }
3650
+ }
3651
+ }
3652
+ }
3653
+
3654
+ @keyframes tabFadeIn {
3655
+ from {
3656
+ opacity: 0;
3657
+ transform: translateY(8px);
3658
+ }
3659
+ to {
3660
+ opacity: 1;
3661
+ transform: translateY(0);
3662
+ }
3663
+ }
3664
+
3665
+ /* Mobile responsive */
3666
+ @media (max-width: 639px) {
3667
+ pds-tabstrip > nav {
3668
+ gap: var(--spacing-1);
3669
+ }
3670
+
3671
+ pds-tabstrip > nav > a {
3672
+ padding: var(--spacing-2) var(--spacing-3);
3673
+ font-size: var(--font-size-sm);
3674
+ }
3675
+
3676
+ pds-tabstrip > pds-tabpanel[data-tabpanel] {
3677
+ padding: var(--spacing-3) 0;
3678
+ }
3679
+ }
3680
+
3681
+
3682
+
3683
+ /* Table Styles - Mobile First */
3684
+
3685
+ table {
3686
+ width: 100%;
3687
+ border-collapse: collapse;
3688
+ margin: 0 0 var(--spacing-6) 0;
3689
+ background-color: var(--color-surface-base);
3690
+ border-radius: var(--radius-md);
3691
+ overflow: hidden;
3692
+ font-size: var(--font-size-sm);
3693
+
3694
+ @media (min-width: 640px) {
3695
+ font-size: var(--font-size-base);
3696
+ }
3697
+ }
3698
+
3699
+ .table-responsive {
3700
+ @media (max-width: 639px) {
3701
+ overflow-x: auto;
3702
+ -webkit-overflow-scrolling: touch;
3703
+ margin: 0 0 var(--spacing-6) 0;
3704
+
3705
+ table {
3706
+ min-width: 600px;
3707
+ margin: 0;
3708
+ }
3709
+ }
3710
+ }
3711
+
3712
+ thead {
3713
+ background-color: var(--color-surface-subtle);
3714
+ }
3715
+
3716
+ th {
3717
+ padding: var(--spacing-3) var(--spacing-4);
3718
+ text-align: left;
3719
+ font-weight: var(--font-weight-semibold);
3720
+ color: var(--color-text-primary);
3721
+ border-bottom: 2px solid var(--color-border);
3722
+ }
3723
+
3724
+ td {
3725
+ padding: var(--spacing-3) var(--spacing-4);
3726
+ color: var(--color-text-secondary);
3727
+ border-bottom: 1px solid var(--color-border);
3728
+ }
3729
+
3730
+ tbody {
3731
+ tr {
3732
+ transition: background-color var(--transition-fast);
3733
+
3734
+ &:hover {
3735
+ background-color: var(--color-surface-subtle);
3736
+ }
3737
+
3738
+ &:last-child td {
3739
+ border-bottom: none;
3740
+ }
3741
+ }
3742
+ }
3743
+
3744
+ .table-striped {
3745
+ tbody tr:nth-child(even) {
3746
+ background-color: var(--color-surface-subtle);
3747
+ }
3748
+ }
3749
+
3750
+ .table-bordered {
3751
+ border: 1px solid var(--color-border);
3752
+
3753
+ th, td {
3754
+ border: 1px solid var(--color-border);
3755
+ }
3756
+ }
3757
+
3758
+ .table-compact {
3759
+ th, td {
3760
+ padding: var(--spacing-2) var(--spacing-3);
3761
+ }
3762
+ }
3763
+
3764
+
3765
+
3766
+ /* Card component */
3767
+
3768
+ .card {
3769
+ background: var(--color-surface-base);
3770
+ border-radius: var(--radius-md);
3771
+ padding: var(--spacing-4);
3772
+
3773
+ &-elevated {
3774
+ background: var(--color-surface-elevated);
3775
+ box-shadow: var(--shadow-md);
3776
+ }
3777
+
3778
+ &-outlined,
3779
+ &-basic {
3780
+ background: var(--color-surface-base);
3781
+ border: 1px solid var(--color-border);
3782
+ }
3783
+
3784
+ &-interactive:hover {
3785
+ transform: translateY(-2px);
3786
+ box-shadow: var(--shadow-lg);
3787
+ transition: transform var(--transition-fast), box-shadow var(--transition-fast);
3788
+ }
3789
+ }
3790
+
3791
+ /* Custom Scrollbars */
3792
+
3793
+ ::-webkit-scrollbar {
3794
+ width: 12px;
3795
+ height: 12px;
3796
+
3797
+ &-track {
3798
+ background: transparent;
3799
+ }
3800
+
3801
+ &-thumb {
3802
+ background: var(--color-secondary-300);
3803
+ border-radius: var(--radius-full);
3804
+ border: 3px solid transparent;
3805
+ background-clip: padding-box;
3806
+ transition: background-color var(--transition-fast);
3807
+
3808
+ &:hover {
3809
+ background: var(--color-secondary-400);
3810
+ border: 2px solid transparent;
3811
+ background-clip: padding-box;
3812
+ }
3813
+
3814
+ &:active {
3815
+ background: var(--color-secondary-500);
3816
+ border: 2px solid transparent;
3817
+ background-clip: padding-box;
3818
+ }
3819
+
3820
+ @media (prefers-color-scheme: dark) {
3821
+ background: var(--color-secondary-600);
3822
+
3823
+ &:hover {
3824
+ background: var(--color-secondary-500);
3825
+ }
3826
+
3827
+ &:active {
3828
+ background: var(--color-secondary-400);
3829
+ }
3830
+ }
3831
+ }
3832
+ }
3833
+
3834
+ * {
3835
+ scrollbar-width: thin;
3836
+ scrollbar-color: var(--color-secondary-300) transparent;
3837
+
3838
+ @media (prefers-color-scheme: dark) {
3839
+ scrollbar-color: var(--color-secondary-600) transparent;
3840
+ }
3841
+ }
3842
+
3843
+ /* Hover effect for scrollable containers */
3844
+ *:hover {
3845
+ scrollbar-color: var(--color-secondary-400) transparent;
3846
+ }
3847
+
3848
+ @media (prefers-color-scheme: dark) {
3849
+ *:hover {
3850
+ scrollbar-color: var(--color-secondary-500) transparent;
3851
+ }
3852
+ }
3853
+
3854
+
3855
+
3856
+ /* Alert dark mode adjustments */
3857
+ html[data-theme="dark"] .alert-success {
3858
+ background-color: var(--color-success-50);
3859
+ border-color: var(--color-success-500);
3860
+ color: var(--color-success-900);
3861
+ }
3862
+
3863
+ html[data-theme="dark"] .alert-info {
3864
+ background-color: var(--color-info-50);
3865
+ border-color: var(--color-info-500);
3866
+ color: var(--color-info-900);
3867
+ }
3868
+
3869
+ html[data-theme="dark"] .alert-warning {
3870
+ background-color: var(--color-warning-50);
3871
+ border-color: var(--color-warning-500);
3872
+ color: var(--color-warning-900);
3873
+ }
3874
+
3875
+ html[data-theme="dark"] .alert-danger,
3876
+ html[data-theme="dark"] .alert-error {
3877
+ background-color: var(--color-danger-50);
3878
+ border-color: var(--color-danger-500);
3879
+ color: var(--color-danger-900);
3880
+ }
3881
+
3882
+ /* Dim images in dark mode */
3883
+ html[data-theme="dark"] img,
3884
+ html[data-theme="dark"] video {
3885
+ opacity: 0.8;
3886
+ transition: opacity var(--transition-normal);
3887
+ }
3888
+
3889
+ html[data-theme="dark"] img:hover,
3890
+ html[data-theme="dark"] video:hover {
3891
+ opacity: 1;
3892
+ }
3893
+
3894
+ }
3895
+ `;