@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,1944 @@
1
+ @layer components {
2
+
3
+ /* Semantic HTML Elements (low-specificity via :where()) */
4
+
5
+ :where(blockquote) {
6
+ margin: 0 0 var(--spacing-4) 0;
7
+ padding: var(--spacing-4) var(--spacing-6);
8
+ border-left: 4px solid var(--color-primary-500);
9
+ background-color: var(--color-surface-subtle);
10
+ border-radius: var(--radius-md);
11
+ font-style: italic;
12
+ color: var(--color-text-secondary);
13
+
14
+ :where(p):last-child {
15
+ margin-bottom: 0;
16
+ }
17
+
18
+ :where(cite) {
19
+ display: block;
20
+ margin-top: var(--spacing-2);
21
+ font-size: var(--font-size-sm);
22
+ font-style: normal;
23
+ color: var(--color-text-tertiary);
24
+
25
+ &::before {
26
+ content: "— ";
27
+ }
28
+ }
29
+ }
30
+
31
+ :where(hr) {
32
+ margin: var(--spacing-8) 0;
33
+ border: none;
34
+ border-top: 1px solid var(--color-border);
35
+ height: 0;
36
+ }
37
+
38
+ :where(dl) {
39
+ margin: 0 0 var(--spacing-4) 0;
40
+ }
41
+
42
+ :where(dt) {
43
+ font-weight: var(--font-weight-semibold);
44
+ color: var(--color-text-primary);
45
+ margin-top: var(--spacing-3);
46
+
47
+ &:first-child {
48
+ margin-top: 0;
49
+ }
50
+ }
51
+
52
+ :where(dd) {
53
+ margin: var(--spacing-1) 0 var(--spacing-3) var(--spacing-6);
54
+ color: var(--color-text-secondary);
55
+ }
56
+
57
+ :where(nav), :where(header), :where(footer) {
58
+ display: block;
59
+ }
60
+
61
+ :where(header), :where(footer) {
62
+ width: 100%;
63
+ }
64
+
65
+ :where(article), :where(section), :where(aside) {
66
+ display: block;
67
+ margin-bottom: var(--spacing-6);
68
+
69
+ & > *:last-child {
70
+ margin-bottom: 0;
71
+ }
72
+ }
73
+
74
+ :where(mark) {
75
+ background-color: var(--color-warning-200);
76
+ color: var(--color-warning-900);
77
+ padding: 0 var(--spacing-1);
78
+ border-radius: var(--radius-sm);
79
+ }
80
+
81
+ :where(kbd) {
82
+ display: inline-block;
83
+ padding: var(--spacing-1) var(--spacing-2);
84
+ font-family: var(--font-family-mono);
85
+ font-size: var(--font-size-sm);
86
+ color: var(--color-text-primary);
87
+ background-color: var(--color-surface-elevated);
88
+ border: 1px solid var(--color-border);
89
+ border-radius: var(--radius-sm);
90
+ box-shadow: 0 2px 0 0 var(--color-border);
91
+ }
92
+
93
+ :where(abbr[title]) {
94
+ text-decoration: underline dotted;
95
+ cursor: help;
96
+ text-decoration-thickness: 1px;
97
+ }
98
+
99
+ :where(time) {
100
+ font-variant-numeric: tabular-nums;
101
+ }
102
+
103
+ :where(address) {
104
+ font-style: normal;
105
+ line-height: var(--font-line-height-relaxed);
106
+ margin: 0 0 var(--spacing-4) 0;
107
+ }
108
+
109
+ :where(details):not(.accordion *) {
110
+ margin: 0 0 var(--spacing-2) 0;
111
+ border: 1px solid var(--color-border);
112
+ border-radius: var(--radius-md);
113
+ background-color: var(--color-surface-base);
114
+
115
+ &[open] :where(summary) {
116
+ border-bottom: 1px solid var(--color-border);
117
+ background-color: var(--color-surface-subtle);
118
+
119
+ &::after {
120
+ transform: rotate(270deg);
121
+ }
122
+ }
123
+
124
+ & > *:not(:where(summary)) {
125
+ padding: var(--spacing-4);
126
+ }
127
+ }
128
+
129
+ :where(summary) {
130
+ padding: var(--spacing-3) var(--spacing-4);
131
+ cursor: pointer;
132
+ border-radius: var(--radius-md);
133
+ font-weight: var(--font-weight-medium);
134
+ user-select: none;
135
+ list-style: none;
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: space-between;
139
+ transition: background-color var(--transition-fast);
140
+
141
+ &::-webkit-details-marker {
142
+ display: none;
143
+ }
144
+
145
+ &::after {
146
+ content: "›";
147
+ display: inline-block;
148
+ transform: rotate(90deg);
149
+ transition: transform var(--transition-fast);
150
+ font-size: var(--font-size-xl);
151
+ font-weight: var(--font-weight-bold);
152
+ color: var(--color-text-secondary);
153
+ }
154
+
155
+ &:hover {
156
+ background-color: var(--color-surface-subtle);
157
+ }
158
+ }
159
+
160
+ /* Dialog styles moved to #generateDialogStyles() */
161
+
162
+
163
+
164
+ /* Mobile-First Form Styles - Generated from Design Config */
165
+ form {
166
+ margin: 0;
167
+ width: 100%;
168
+ }
169
+
170
+ fieldset {
171
+ margin: 0 0 var(--spacing-2) 0;
172
+ padding: var(--spacing-5);
173
+ width: 100%;
174
+ background-color: color-mix(in oklab, var(--color-surface-subtle) 50%, transparent 50%);
175
+
176
+ /* Unified styling for radio groups and checkbox groups */
177
+ &[role="radiogroup"],
178
+ &[role="group"] {
179
+ display: flex;
180
+ flex-direction: column;
181
+ gap: var(--spacing-2);
182
+ padding: 0;
183
+ background-color: transparent;
184
+
185
+ label {
186
+ display: flex;
187
+ align-items: center;
188
+ gap: var(--spacing-3);
189
+ padding: var(--spacing-1) 0;
190
+ cursor: pointer;
191
+ min-height: auto;
192
+ border: none;
193
+ background: none;
194
+ font-weight: var(--font-weight-normal);
195
+ margin-bottom: 0;
196
+
197
+ &:hover {
198
+ color: var(--color-primary-700);
199
+ }
200
+ }
201
+
202
+ input[type="radio"],
203
+ input[type="checkbox"] {
204
+ position: static;
205
+ opacity: 1;
206
+ width: var(--spacing-5);
207
+ height: var(--spacing-5);
208
+ min-height: var(--spacing-5);
209
+ margin: 0;
210
+ cursor: pointer;
211
+ flex-shrink: 0;
212
+ accent-color: var(--color-primary-600);
213
+ appearance: auto;
214
+ -webkit-appearance: auto;
215
+ -moz-appearance: auto;
216
+
217
+ &:focus {
218
+ outline: 2px solid var(--color-primary-500);
219
+ outline-offset: 2px;
220
+ }
221
+ }
222
+ }
223
+
224
+ }
225
+
226
+
227
+
228
+ /* Nested legend scaling: reduce font-size for deeper sub-forms */
229
+ fieldset > legend { font-size: var(--font-size-lg); }
230
+ fieldset fieldset > legend { font-size: var(--font-size-base); }
231
+ fieldset fieldset fieldset > legend { font-size: var(--font-size-sm); }
232
+
233
+ .form-container {
234
+ display: grid;
235
+ gap: var(--spacing-6);
236
+ width: 100%;
237
+ }
238
+
239
+ .fields {
240
+ display: grid;
241
+ gap: var(--spacing-4);
242
+ }
243
+
244
+ label {
245
+ display: block;
246
+ margin-bottom: var(--spacing-3);
247
+ font-weight: var(--font-weight-medium);
248
+ color: var(--color-text-primary);
249
+ font-size: var(--font-size-sm);
250
+ line-height: var(--font-line-height-normal);
251
+ }
252
+
253
+ [data-label] {
254
+ display: block;
255
+ font-weight: var(--font-weight-medium);
256
+ color: var(--color-text-primary);
257
+ font-size: var(--font-size-sm);
258
+ margin-bottom: var(--spacing-2);
259
+ }
260
+
261
+ [data-open]{
262
+ [data-label]{
263
+ margin-bottom: 0;
264
+ }
265
+ }
266
+
267
+ .field-description {
268
+ font-size: var(--font-size-xs);
269
+ color: var(--color-text-secondary);
270
+ margin-top: var(--spacing-1);
271
+ line-height: var(--font-line-height-relaxed);
272
+ }
273
+
274
+ input, textarea, select {
275
+ width: 100%;
276
+ min-height: 40px;
277
+ padding: calc(var(--spacing-1) * 0.75) var(--spacing-4);
278
+ border: 1px solid var(--color-border);
279
+ border-radius: var(--radius-md);
280
+ font-family: var(--font-family-body);
281
+ font-size: var(--font-size-base);
282
+ line-height: var(--font-line-height-normal);
283
+ background-color: var(--color-input-bg);
284
+ color: var(--color-text-primary);
285
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast);
286
+ touch-action: manipulation;
287
+ appearance: none;
288
+ -webkit-appearance: none;
289
+
290
+ &:focus {
291
+ outline: none;
292
+ border-color: var(--color-primary-500);
293
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
294
+ background-color: var(--color-surface-base);
295
+ }
296
+
297
+ &:disabled {
298
+ background-color: var(--color-input-disabled-bg);
299
+ color: var(--color-input-disabled-text);
300
+ border-color: var(--color-border);
301
+ cursor: not-allowed;
302
+ opacity: 0.6;
303
+ }
304
+
305
+ &:invalid {
306
+ border-color: var(--color-danger-500);
307
+
308
+ &:focus {
309
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-danger-500) 30%, transparent);
310
+ }
311
+ }
312
+ }
313
+
314
+ input[type="range"] {
315
+ padding: 0;
316
+ background: transparent;
317
+ min-height: auto;
318
+ }
319
+
320
+ /* Make range visually match other inputs */
321
+ input[type="range"] {
322
+ -webkit-appearance: none;
323
+ appearance: none;
324
+ height: var(--input-min-height, 40px); /* align control height with inputs */
325
+ width: 100%;
326
+ }
327
+
328
+ /* Track and thumb styling - using CSS nesting to reduce repetition */
329
+ input[type="range"] {
330
+ /* WebKit track */
331
+ &::-webkit-slider-runnable-track {
332
+ height: var(--range-track-height, 8px);
333
+ background: var(--color-input-bg);
334
+ border-radius: var(--radius-full);
335
+ }
336
+
337
+ /* WebKit thumb */
338
+ &::-webkit-slider-thumb {
339
+ -webkit-appearance: none;
340
+ appearance: none;
341
+ width: var(--range-thumb-size, 28px);
342
+ height: var(--range-thumb-size, 28px);
343
+ margin-top: calc((var(--range-track-height, 8px) - var(--range-thumb-size, 28px)) / 2);
344
+ background: color-mix(in srgb, var(--color-primary-500) 15%, var(--color-surface-base));
345
+ border-radius: 50%;
346
+ box-shadow: var(--shadow-sm);
347
+ cursor: grab;
348
+ border: 1px solid color-mix(in srgb, var(--color-primary-500) 30%, var(--color-border));
349
+ }
350
+
351
+ /* Mozilla track */
352
+ &::-moz-range-track {
353
+ height: var(--range-track-height, 8px);
354
+ background: var(--color-input-bg);
355
+ border-radius: var(--radius-full);
356
+ }
357
+
358
+ /* Mozilla thumb */
359
+ &::-moz-range-thumb {
360
+ width: var(--range-thumb-size, 28px);
361
+ height: var(--range-thumb-size, 28px);
362
+ background: color-mix(in srgb, var(--color-primary-500) 15%, var(--color-surface-base));
363
+ border-radius: 50%;
364
+ box-shadow: var(--shadow-sm);
365
+ border: 1px solid color-mix(in srgb, var(--color-primary-500) 30%, var(--color-border));
366
+ transform: translateY(calc((var(--range-track-height, 8px) - var(--range-thumb-size, 28px)) / 2));
367
+ }
368
+
369
+ /* Hover and focus states for WebKit */
370
+ &:hover::-webkit-slider-thumb,
371
+ &:focus-visible::-webkit-slider-thumb {
372
+ cursor: grabbing;
373
+ background: var(--color-primary-500);
374
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
375
+ border-color: var(--color-primary-600);
376
+ }
377
+
378
+ /* Active state for WebKit */
379
+ &:active::-webkit-slider-thumb {
380
+ background: var(--color-primary-600);
381
+ }
382
+
383
+ /* Hover and focus states for Mozilla */
384
+ &:hover::-moz-range-thumb,
385
+ &:focus-visible::-moz-range-thumb {
386
+ background: var(--color-primary-500);
387
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
388
+ border-color: var(--color-primary-600);
389
+ cursor: grabbing;
390
+ }
391
+
392
+ /* Active state for Mozilla */
393
+ &:active::-moz-range-thumb {
394
+ background: var(--color-primary-600);
395
+ }
396
+ }
397
+
398
+ /* Focus style for container to match input focus */
399
+ .range-container:focus-within {
400
+ border-color: var(--color-primary-500);
401
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary-500) 30%, transparent);
402
+ }
403
+
404
+ input[type="range"]:active::-moz-range-thumb {
405
+ background: var(--color-primary-600);
406
+ }
407
+
408
+ input[type="color"] {
409
+ -webkit-appearance: none;
410
+ padding: 0;
411
+ width: 3rem;
412
+ height: 3rem;
413
+ border-radius: 0.75rem; /* your radius */
414
+ overflow: hidden; /* important */
415
+ cursor: pointer;
416
+
417
+ /* The wrapper */
418
+ &::-webkit-color-swatch-wrapper {
419
+ padding: 0;
420
+ border-radius: inherit;
421
+ }
422
+
423
+ /* The swatch (the actual color box) */
424
+ &::-webkit-color-swatch {
425
+ border: none;
426
+ border-radius: inherit;
427
+ }
428
+ }
429
+
430
+ /* Button-style checkbox inputs outside of fieldsets */
431
+ .checkbox-container input[type="checkbox"] {
432
+ appearance: none;
433
+ -webkit-appearance: none;
434
+ -moz-appearance: none;
435
+ position: absolute;
436
+ opacity: 0;
437
+ width: 0;
438
+ height: 0;
439
+ margin: 0;
440
+ padding: 0;
441
+ pointer-events: none;
442
+ }
443
+
444
+ label:has(input[type="checkbox"]):not(fieldset label):not(label[data-toggle]),
445
+ input[type="checkbox"] + label:not(fieldset label):not(label[data-toggle]) {
446
+ display: inline-flex;
447
+ align-items: center;
448
+ justify-content: center;
449
+ min-height: calc(44px * 0.75);
450
+ padding: calc(var(--spacing-1) * 0.6) calc(var(--spacing-4) * 0.85);
451
+ border: 1px solid var(--color-border);
452
+ border-radius: var(--radius-md);
453
+ font-family: var(--font-family-body);
454
+ font-size: var(--font-size-sm);
455
+ font-weight: var(--font-weight-medium);
456
+ line-height: 1.2;
457
+ cursor: pointer;
458
+ transition: all var(--transition-fast);
459
+ text-decoration: none;
460
+ touch-action: manipulation;
461
+ user-select: none;
462
+ background-color: transparent;
463
+ color: var(--color-text-primary);
464
+ margin: 0;
465
+ flex: 0 1 auto;
466
+ white-space: nowrap;
467
+
468
+ &:hover {
469
+ background-color: var(--color-surface-subtle);
470
+ border-color: var(--color-primary-500);
471
+ }
472
+ }
473
+
474
+ label:has(input[type="checkbox"]:checked):not(fieldset label):not(label[data-toggle]),
475
+ input[type="checkbox"]:checked + label:not(fieldset label):not(label[data-toggle]) {
476
+ background-color: color-mix(in oklab, var(--color-primary-500) 8%, transparent);
477
+ color: var(--color-primary-700);
478
+ border-color: var(--color-primary-500);
479
+ border-width: 2px;
480
+ font-weight: var(--font-weight-semibold);
481
+
482
+ &:hover {
483
+ background-color: color-mix(in oklab, var(--color-primary-500) 15%, transparent);
484
+ border-color: var(--color-primary-600);
485
+ }
486
+ }
487
+
488
+ label:has(input[type="checkbox"]:focus):not(fieldset label):not(label[data-toggle]),
489
+ input[type="checkbox"]:focus + label:not(fieldset label):not(label[data-toggle]) {
490
+ outline: none;
491
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
492
+ }
493
+
494
+ label:has(input[type="checkbox"]:disabled):not(fieldset label):not(label[data-toggle]),
495
+ input[type="checkbox"]:disabled + label:not(fieldset label):not(label[data-toggle]) {
496
+ background-color: var(--color-input-disabled-bg);
497
+ color: var(--color-input-disabled-text);
498
+ border-color: var(--color-border);
499
+ cursor: not-allowed;
500
+ opacity: 0.6;
501
+ }
502
+
503
+ label:has(input[type="checkbox"]:checked:disabled):not(fieldset label):not(label[data-toggle]),
504
+ input[type="checkbox"]:checked:disabled + label:not(fieldset label):not(label[data-toggle]) {
505
+ background-color: var(--color-input-disabled-bg);
506
+ color: var(--color-input-disabled-text);
507
+ border-color: var(--color-border);
508
+ }
509
+
510
+ /* Keep default checkbox/radio for inputs NOT in special containers */
511
+ input[type="checkbox"]:not(fieldset input[type="checkbox"]):not(.checkbox-container input[type="checkbox"]),
512
+ input[type="radio"]:not(fieldset input[type="radio"]) {
513
+ width: var(--spacing-5);
514
+ height: var(--spacing-5);
515
+ min-height: var(--spacing-5);
516
+ margin-right: var(--spacing-2);
517
+ cursor: pointer;
518
+ position: static;
519
+ opacity: 1;
520
+ appearance: auto;
521
+ -webkit-appearance: auto;
522
+
523
+ &:disabled {
524
+ cursor: not-allowed;
525
+ }
526
+ }
527
+
528
+ /* Button-style radio and checkbox groups with .buttons class */
529
+ fieldset[role="radiogroup"].buttons,
530
+ fieldset[role="group"].buttons {
531
+ flex-direction: row;
532
+ flex-wrap: wrap;
533
+ gap: var(--spacing-3);
534
+
535
+ input[type="radio"],
536
+ input[type="checkbox"] {
537
+ appearance: none;
538
+ -webkit-appearance: none;
539
+ -moz-appearance: none;
540
+ position: absolute;
541
+ opacity: 0;
542
+ width: 0;
543
+ height: 0;
544
+ margin: 0;
545
+ padding: 0;
546
+ pointer-events: none;
547
+ }
548
+
549
+ label {
550
+ display: inline-flex;
551
+ align-items: center;
552
+ justify-content: center;
553
+ min-height: calc(44px * 0.75);
554
+ padding: calc(var(--spacing-1) * 0.6) calc(var(--spacing-4) * 0.85);
555
+ border: 1px solid var(--color-border);
556
+ border-radius: var(--radius-md);
557
+ font-family: var(--font-family-body);
558
+ font-size: var(--font-size-sm);
559
+ font-weight: var(--font-weight-medium);
560
+ line-height: 1.2;
561
+ cursor: pointer;
562
+ transition: all var(--transition-fast);
563
+ text-decoration: none;
564
+ touch-action: manipulation;
565
+ user-select: none;
566
+ background-color: transparent;
567
+ color: var(--color-text-primary);
568
+ margin: 0;
569
+ flex: 0 1 auto;
570
+ white-space: nowrap;
571
+
572
+ &:hover {
573
+ background-color: var(--color-surface-subtle);
574
+ border-color: var(--color-primary-500);
575
+ color: var(--color-text-primary);
576
+ }
577
+
578
+ &:has([disabled]){
579
+ pointer-events: none;
580
+ }
581
+ }
582
+
583
+ label:has(input[type="radio"]:checked),
584
+ label:has(input[type="checkbox"]:checked) {
585
+ background-color: color-mix(in oklab, var(--color-primary-500) 8%, transparent);
586
+ border-color: var(--color-primary-500);
587
+ border-width: 2px;
588
+ font-weight: var(--font-weight-semibold);
589
+
590
+ &:hover {
591
+ background-color: color-mix(in oklab, var(--color-primary-500) 15%, transparent);
592
+ border-color: var(--color-primary-600);
593
+ }
594
+ }
595
+
596
+ label:has(input[type="radio"]:focus),
597
+ label:has(input[type="checkbox"]:focus) {
598
+ outline: none;
599
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
600
+ }
601
+
602
+ label:has(input[type="radio"]:disabled),
603
+ label:has(input[type="checkbox"]:disabled) {
604
+ background-color: var(--color-input-disabled-bg);
605
+ color: var(--color-input-disabled-text);
606
+ border-color: var(--color-border);
607
+ cursor: not-allowed;
608
+ opacity: 0.6;
609
+ }
610
+
611
+ label:has(input[type="radio"]:checked:disabled),
612
+ label:has(input[type="checkbox"]:checked:disabled) {
613
+ background-color: var(--color-input-disabled-bg);
614
+ color: var(--color-input-disabled-text);
615
+ border-color: var(--color-border);
616
+ }
617
+ }
618
+
619
+ /* Toggle switches - enhanced checkboxes with data-toggle attribute */
620
+ label[data-toggle] {
621
+ display: inline-flex;
622
+ align-items: normal;
623
+ gap: var(--spacing-3);
624
+ cursor: pointer;
625
+ user-select: none;
626
+ padding: 0;
627
+ background: transparent;
628
+ border: none;
629
+ min-height: auto;
630
+ font-weight: var(--font-weight-normal);
631
+
632
+ /* Hide the original checkbox in toggle switches */
633
+ input[type="checkbox"] {
634
+ display: none;
635
+ }
636
+
637
+ /* Toggle switch container */
638
+ .toggle-switch {
639
+ position: relative;
640
+ display: inline-block;
641
+ width: 44px;
642
+ height: 24px;
643
+ background-color: var(--color-gray-300);
644
+ border-radius: var(--radius-full);
645
+ transition: background-color 200ms ease;
646
+ cursor: pointer;
647
+ flex-shrink: 0;
648
+ }
649
+
650
+ /* Toggle switch knob */
651
+ .toggle-knob {
652
+ position: absolute;
653
+ top: 2px;
654
+ left: 2px;
655
+ width: 20px;
656
+ height: 20px;
657
+ background-color: #ffffff;
658
+ border-radius: 50%;
659
+ transition: left 200ms ease;
660
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
661
+ }
662
+
663
+ /* Toggle switch when checked - using :has() selector */
664
+ &:has(input[type="checkbox"]:checked) .toggle-switch {
665
+ background-color: var(--color-primary-fill);
666
+ }
667
+
668
+
669
+ /* Toggle knob when checked - always moves to the right */
670
+ &:has(input[type="checkbox"]:checked) .toggle-knob {
671
+ left: 22px;
672
+ }
673
+
674
+ /* Focus state for toggle switch */
675
+ &:has(input[type="checkbox"]:focus) .toggle-switch {
676
+ outline: 2px solid var(--color-primary-500);
677
+ outline-offset: 2px;
678
+ }
679
+
680
+ /* Focus visible state when label is focused via keyboard */
681
+ &:focus-visible .toggle-switch {
682
+ outline: 2px solid var(--color-primary-500);
683
+ outline-offset: 2px;
684
+ }
685
+
686
+ /* Remove default outline on label itself */
687
+ &:focus {
688
+ outline: none;
689
+ }
690
+
691
+ /* Disabled state */
692
+ &:has(input[type="checkbox"]:disabled) {
693
+ cursor: not-allowed;
694
+ opacity: 0.6;
695
+
696
+ .toggle-switch {
697
+ opacity: 0.5;
698
+ cursor: not-allowed;
699
+ }
700
+ }
701
+ }
702
+
703
+ input[type="file"] {
704
+ padding: var(--spacing-2) var(--spacing-4);
705
+ cursor: pointer;
706
+ }
707
+
708
+ /* Textareas */
709
+ textarea {
710
+ min-height: calc(var(--spacing-4) * 5);
711
+ padding: var(--spacing-3) var(--spacing-4);
712
+ resize: vertical;
713
+ line-height: var(--font-line-height-relaxed);
714
+ }
715
+
716
+ /* Select dropdowns */
717
+ select {
718
+ cursor: pointer;
719
+ 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");
720
+ background-position: right var(--spacing-2) center;
721
+ background-repeat: no-repeat;
722
+ background-size: 1.5em 1.5em;
723
+ padding-right: var(--spacing-8);
724
+ }
725
+
726
+ /* Button styling */
727
+ button, .btn, input[type="submit"], input[type="button"], input[type="reset"] {
728
+ display: inline-flex;
729
+ gap: var(--spacing-1);
730
+ align-items: center;
731
+ justify-content: center;
732
+ min-height: 44px;
733
+ padding: calc(var(--spacing-1) * 1) var(--spacing-6);
734
+ border: 1px solid transparent;
735
+ border-radius: var(--radius-md);
736
+ font-family: var(--font-family-body);
737
+ font-size: var(--font-size-base);
738
+ font-weight: var(--font-weight-medium);
739
+ line-height: 1;
740
+ cursor: pointer;
741
+ transition: all var(--transition-fast);
742
+ text-decoration: none;
743
+ touch-action: manipulation;
744
+ user-select: none;
745
+ background-color: var(--color-surface-base);
746
+ color: var(--color-text-primary);
747
+ border-color: var(--color-border);
748
+
749
+ /* Only apply generic hover to non-variant buttons */
750
+ &:hover:not(.btn-primary):not(.btn-secondary):not(.btn-outline) {
751
+ background-color: var(--color-surface-elevated);
752
+ }
753
+
754
+ &:focus {
755
+ outline: none;
756
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
757
+ }
758
+
759
+ &:disabled {
760
+ background-color: var(--color-input-disabled-bg);
761
+ color: var(--color-input-disabled-text);
762
+ border-color: var(--color-input-disabled-bg);
763
+ cursor: not-allowed;
764
+ opacity: 0.6;
765
+ }
766
+ }
767
+
768
+ .btn-primary {
769
+ background-color: var(--color-primary-fill);
770
+ color: white;
771
+ border-color: var(--color-primary-fill);
772
+
773
+ &:hover {
774
+ background-color: color-mix(in oklab, var(--color-primary-fill) 90%, black 10%);
775
+ border-color: color-mix(in oklab, var(--color-primary-fill) 90%, black 10%);
776
+ color: white;
777
+ }
778
+
779
+ &:active {
780
+ background-color: color-mix(in oklab, var(--color-primary-fill) 80%, black 20%);
781
+ border-color: color-mix(in oklab, var(--color-primary-fill) 80%, black 20%);
782
+ color: white;
783
+ }
784
+
785
+ &:focus {
786
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary-500) 30%, transparent);
787
+ }
788
+
789
+ &:disabled {
790
+ background-color: var(--color-input-disabled-bg);
791
+ color: var(--color-input-disabled-text);
792
+ border-color: var(--color-input-disabled-bg);
793
+ }
794
+ }
795
+
796
+ .btn-secondary {
797
+ background-color: var(--color-surface-base);
798
+ color: var(--color-text-primary);
799
+ border-color: var(--color-border);
800
+
801
+ &:hover {
802
+ background-color: var(--color-surface-elevated);
803
+ }
804
+ }
805
+
806
+ .btn-outline {
807
+ background-color: transparent;
808
+ color: var(--color-primary-500);
809
+ border-color: var(--color-primary-500);
810
+
811
+ &:hover {
812
+ background-color: var(--color-primary-500);
813
+ color: var(--color-primary-contrast, #ffffff);
814
+ border-color: var(--color-primary-500);
815
+
816
+ pds-icon {
817
+ color: var(--color-primary-contrast, #ffffff);
818
+ }
819
+ }
820
+
821
+ &:active {
822
+ background-color: color-mix(in oklab, var(--color-primary-500) 80%, black 20%);
823
+ border-color: color-mix(in oklab, var(--color-primary-500) 80%, black 20%);
824
+ color: var(--color-primary-contrast, #ffffff);
825
+
826
+ pds-icon {
827
+ color: var(--color-primary-contrast, #ffffff);
828
+ }
829
+ }
830
+
831
+ &:disabled {
832
+ background-color: transparent;
833
+ color: var(--color-input-disabled-text);
834
+ border-color: var(--color-input-disabled-bg);
835
+ }
836
+ }
837
+
838
+ .btn-sm {
839
+ padding: var(--spacing-2) var(--spacing-4);
840
+ font-size: var(--font-size-sm);
841
+ min-height: calc(44px * 0.8);
842
+ }
843
+
844
+ .btn-xs {
845
+ padding: var(--spacing-1) var(--spacing-2);
846
+ font-size: var(--font-size-xs);
847
+ min-height: calc(44px * 0.6);
848
+ }
849
+
850
+
851
+ .btn-lg {
852
+ padding: var(--spacing-4) var(--spacing-8);
853
+ font-size: var(--font-size-lg);
854
+ min-height: calc(44px * 1.2);
855
+ }
856
+
857
+ /* Working/loading state for buttons */
858
+ button.btn-working,
859
+ a.btn-working {
860
+ cursor: wait;
861
+ pointer-events: none;
862
+ opacity: 0.6;
863
+
864
+ pds-icon:first-child {
865
+ animation: pds-spin 0.8s linear infinite;
866
+ }
867
+ }
868
+
869
+ @keyframes pds-spin {
870
+ to { transform: rotate(360deg); }
871
+ }
872
+
873
+ /* Skeleton loading animation */
874
+ .skeleton {
875
+ background: linear-gradient(
876
+ 90deg,
877
+ color-mix(in oklab, var(--color-surface-base) 92%, var(--color-text-primary) 8%) 0%,
878
+ color-mix(in oklab, var(--color-surface-base) 85%, var(--color-text-primary) 15%) 50%,
879
+ color-mix(in oklab, var(--color-surface-base) 92%, var(--color-text-primary) 8%) 100%
880
+ );
881
+ background-size: 200% 100%;
882
+ animation: pds-skeleton 1.5s ease-in-out infinite;
883
+ border-radius: var(--radius-sm);
884
+
885
+ &::before {
886
+ content: '\00a0';
887
+ }
888
+ }
889
+
890
+ @keyframes pds-skeleton {
891
+ 0% { background-position: 200% 0; }
892
+ 100% { background-position: -200% 0; }
893
+ }
894
+
895
+ /* Form utility classes */
896
+ .range-container {
897
+ display: flex;
898
+ align-items: center;
899
+ gap: var(--spacing-3);
900
+ width: 100%;
901
+ background: var(--color-input-bg);
902
+ border: 1px solid var(--color-border);
903
+ border-radius: var(--radius-md);
904
+ min-height: var(--input-min-height, 40px);
905
+ position: relative;
906
+
907
+ input[type="range"] {
908
+ border: none;
909
+ }
910
+ }
911
+
912
+ .range-bubble {
913
+ position: absolute;
914
+ top: calc(-1 * (var(--range-thumb-size, 28px) + var(--spacing-2)));
915
+ transform: translateX(-50%);
916
+ min-width: calc(var(--range-thumb-size, 28px) * 0.8);
917
+ padding: var(--spacing-1) var(--spacing-2);
918
+ border-radius: var(--radius-md);
919
+ background: var(--color-surface-base);
920
+ color: var(--color-text-primary);
921
+ text-align: center;
922
+ font-size: var(--font-size-sm);
923
+ box-shadow: var(--shadow-md);
924
+ opacity: 0;
925
+ pointer-events: none;
926
+ transition: opacity 150ms ease, transform 150ms ease;
927
+
928
+ &.visible {
929
+ opacity: 1;
930
+ }
931
+ }
932
+
933
+ /* Anchor bubble to the thumb position using left (set by enhancer)
934
+ and center with translateX(-50%). */
935
+
936
+ /* Array field styling */
937
+ .array-list {
938
+ display: flex;
939
+ flex-direction: column;
940
+ gap: var(--spacing-4);
941
+ margin-bottom: var(--spacing-4);
942
+ }
943
+
944
+ .array-item {
945
+ position: relative;
946
+ padding: var(--spacing-4);
947
+ border: 1px solid var(--color-border);
948
+ border-radius: var(--radius-md);
949
+ background-color: var(--color-surface-base);
950
+
951
+ fieldset {
952
+ background-color: transparent;
953
+ margin-bottom: var(--spacing-3);
954
+
955
+ &:last-of-type {
956
+ margin-bottom: 0;
957
+ }
958
+ }
959
+
960
+ .array-controls {
961
+ padding-top: var(--spacing-3);
962
+ border-top: 1px solid var(--color-border);
963
+ margin-top: var(--spacing-4);
964
+ }
965
+ }
966
+
967
+ .array-controls {
968
+ display: flex;
969
+ gap: var(--spacing-2);
970
+ margin-top: var(--spacing-3);
971
+ flex-wrap: wrap;
972
+
973
+ button {
974
+ padding: var(--spacing-2) var(--spacing-3);
975
+ font-size: var(--font-size-sm);
976
+ min-height: auto;
977
+ }
978
+ }
979
+
980
+ .range-value {
981
+ min-width: var(--spacing-16);
982
+ text-align: right;
983
+ font-weight: var(--font-weight-medium);
984
+ font-size: var(--font-size-sm);
985
+ color: var(--color-text-primary);
986
+ }
987
+
988
+ .checkbox-container {
989
+ display: flex;
990
+ flex-direction: row;
991
+ align-items: center;
992
+ gap: var(--spacing-2);
993
+ flex-wrap: wrap;
994
+
995
+ input[type="checkbox"],
996
+ input[type="radio"] {
997
+ position: absolute;
998
+ opacity: 0;
999
+ }
1000
+ }
1001
+
1002
+
1003
+
1004
+ /* Alert/Notification Styles */
1005
+
1006
+ /* Alias: .semantic-message shares alert base styles */
1007
+ .alert, .semantic-message {
1008
+ padding: var(--spacing-4);
1009
+ border-radius: var(--radius-md);
1010
+ margin: 0 0 var(--spacing-4) 0;
1011
+ border-left: 4px solid;
1012
+ display: flex;
1013
+ align-items: flex-start;
1014
+ gap: var(--spacing-3);
1015
+ font-size: var(--font-size-sm);
1016
+ line-height: var(--font-line-height-relaxed);
1017
+
1018
+ & > *:last-child {
1019
+ margin-bottom: 0;
1020
+ }
1021
+ }
1022
+ /* Variants: success/info/warning/danger mapped to tokens */
1023
+ .alert-success, .semantic-message.success {
1024
+ background-color: var(--color-success-50);
1025
+ border-color: var(--color-success-600);
1026
+ color: var(--color-success-900);
1027
+ }
1028
+ .alert-info, .semantic-message.info {
1029
+ background-color: var(--color-info-50);
1030
+ border-color: var(--color-info-600);
1031
+ color: var(--color-info-900);
1032
+ }
1033
+ .alert-warning, .semantic-message.warning {
1034
+ background-color: var(--color-warning-50);
1035
+ border-color: var(--color-warning-600);
1036
+ color: var(--color-warning-900);
1037
+ }
1038
+ .alert-danger,
1039
+ .alert-error,
1040
+ .semantic-message.danger {
1041
+ background-color: var(--color-danger-50);
1042
+ border-color: var(--color-danger-600);
1043
+ color: var(--color-danger-900);
1044
+ }
1045
+
1046
+ /* Semantic-message content defaults */
1047
+ .semantic-message strong { display: block; }
1048
+ .semantic-message p { margin: 0; font-size: var(--font-size-sm); }
1049
+
1050
+ .alert-title {
1051
+ font-weight: var(--font-weight-semibold);
1052
+ margin: 0 0 var(--spacing-2) 0;
1053
+ font-size: var(--font-size-base);
1054
+ }
1055
+
1056
+ .alert-icon {
1057
+ flex-shrink: 0;
1058
+ display: flex;
1059
+ align-items: center;
1060
+ justify-content: center;
1061
+
1062
+ pds-icon {
1063
+ flex-shrink: 0;
1064
+ }
1065
+ }
1066
+
1067
+ .alert-dismissible {
1068
+ padding-right: var(--spacing-12);
1069
+ position: relative;
1070
+ }
1071
+
1072
+ .alert-close {
1073
+ position: absolute;
1074
+ top: var(--spacing-3);
1075
+ right: var(--spacing-3);
1076
+ background: none;
1077
+ border: none;
1078
+ font-size: var(--font-size-xl);
1079
+ line-height: 1;
1080
+ opacity: 0.6;
1081
+ cursor: pointer;
1082
+ padding: var(--spacing-1);
1083
+ transition: opacity var(--transition-fast);
1084
+
1085
+ &:hover {
1086
+ opacity: 1;
1087
+ }
1088
+ }
1089
+
1090
+
1091
+
1092
+ /* Badge/Pill Styles */
1093
+
1094
+ .badge {
1095
+ display: inline-flex;
1096
+ align-items: center;
1097
+ justify-content: center;
1098
+ padding: var(--spacing-1) var(--spacing-2);
1099
+ font-size: var(--font-size-xs);
1100
+ font-weight: var(--font-weight-semibold);
1101
+ line-height: 1;
1102
+ border-radius: var(--radius-full);
1103
+ white-space: nowrap;
1104
+ vertical-align: middle;
1105
+ background-color: var(--color-gray-200);
1106
+ color: var(--color-gray-800);
1107
+ border-radius: var(--radius-full);
1108
+ }
1109
+
1110
+ .badge-primary {
1111
+ background-color: var(--color-primary-600);
1112
+ color: white;
1113
+ }
1114
+
1115
+ .badge-secondary {
1116
+ background-color: var(--color-secondary-600);
1117
+ color: white;
1118
+ }
1119
+
1120
+ .badge-success {
1121
+ background-color: var(--color-success-600);
1122
+ color: white;
1123
+ }
1124
+
1125
+ .badge-info {
1126
+ background-color: var(--color-info-600);
1127
+ color: white;
1128
+ }
1129
+
1130
+ .badge-warning {
1131
+ background-color: var(--color-warning-600);
1132
+ color: white;
1133
+ }
1134
+
1135
+ .badge-danger {
1136
+ background-color: var(--color-danger-600);
1137
+ color: white;
1138
+ }
1139
+
1140
+ .badge-outline {
1141
+ background-color: transparent;
1142
+ border: 1px solid currentColor;
1143
+
1144
+ &.badge-primary {
1145
+ color: var(--color-text-primary);
1146
+ }
1147
+
1148
+ &.badge-secondary {
1149
+ color: var(--color-secondary-600);
1150
+ }
1151
+
1152
+ &.badge-success {
1153
+ color: var(--color-success-600);
1154
+ }
1155
+
1156
+ &.badge-info {
1157
+ color: var(--color-info-600);
1158
+ }
1159
+
1160
+ &.badge-warning {
1161
+ color: var(--color-warning-600);
1162
+ }
1163
+
1164
+ &.badge-danger {
1165
+ color: var(--color-danger-600);
1166
+ }
1167
+ }
1168
+
1169
+ .badge-sm {
1170
+ padding: 2px var(--spacing-1);
1171
+ font-size: 10px;
1172
+ }
1173
+
1174
+ .badge-lg {
1175
+ padding: var(--spacing-2) var(--spacing-3);
1176
+ font-size: var(--font-size-sm);
1177
+ }
1178
+
1179
+ .pill {
1180
+ padding: var(--spacing-1) var(--spacing-3);
1181
+ border-radius: var(--radius-full);
1182
+ }
1183
+
1184
+
1185
+
1186
+ /* ============================================================================
1187
+ Dialog Primitive
1188
+ Native <dialog> element with PDS integration
1189
+ ============================================================================ */
1190
+
1191
+ /* Dialog base styles */
1192
+ dialog {
1193
+ position: fixed;
1194
+ inset: 0;
1195
+ max-width: min(600px, calc(100vw - var(--spacing-8)));
1196
+ max-height: calc(100vh - var(--spacing-8));
1197
+ margin: auto;
1198
+ padding: 0;
1199
+ border: none;
1200
+ border-radius: var(--radius-lg);
1201
+
1202
+ /* Surface styling - elevated overlay */
1203
+ background-color: var(--surface-overlay-bg);
1204
+ color: var(--surface-overlay-text);
1205
+ box-shadow: 0 8px 32px var(--surface-overlay-shadow);
1206
+
1207
+ /* Smooth transitions */
1208
+ opacity: 0;
1209
+ scale: 0.95;
1210
+ transition:
1211
+ opacity 0.2s ease,
1212
+ scale 0.2s ease,
1213
+ overlay 0.2s ease allow-discrete,
1214
+ display 0.2s ease allow-discrete;
1215
+
1216
+ /* Overflow handling */
1217
+ overflow: hidden;
1218
+ }
1219
+
1220
+ /* Open state */
1221
+ dialog[open] {
1222
+ opacity: 1;
1223
+ scale: 1;
1224
+ }
1225
+
1226
+ /* Starting style for smooth open animation */
1227
+ @starting-style {
1228
+ dialog[open] {
1229
+ opacity: 0;
1230
+ scale: 0.95;
1231
+ }
1232
+ }
1233
+
1234
+ /* Backdrop styling */
1235
+ dialog::backdrop {
1236
+ background: var(--backdrop-bg);
1237
+ backdrop-filter: var(--backdrop-filter);
1238
+ opacity: 0;
1239
+ transition:
1240
+ opacity 0.2s ease,
1241
+ overlay 0.2s ease allow-discrete,
1242
+ display 0.2s ease allow-discrete;
1243
+ }
1244
+
1245
+ dialog[open]::backdrop {
1246
+ opacity: var(--backdrop-opacity, 1);
1247
+ }
1248
+
1249
+ @starting-style {
1250
+ dialog[open]::backdrop {
1251
+ opacity: 0;
1252
+ }
1253
+ }
1254
+
1255
+ /* Form structure - use flexbox instead of contents */
1256
+ dialog form {
1257
+ display: flex;
1258
+ flex-direction: column;
1259
+ height: 100%;
1260
+ margin: 0;
1261
+ }
1262
+
1263
+ /* Dialog fields - to open pds-jsonform subforms */
1264
+ .dialog-field {
1265
+ margin-top: var(--spacing-3);
1266
+ }
1267
+
1268
+ /* Dialog header */
1269
+ dialog {
1270
+ header,
1271
+ form > header {
1272
+ display: flex;
1273
+ align-items: center;
1274
+ justify-content: space-between;
1275
+ gap: var(--spacing-4);
1276
+ padding: var(--spacing-6);
1277
+ border-bottom: 1px solid var(--surface-overlay-border);
1278
+ flex-shrink: 0;
1279
+
1280
+ h2,
1281
+ h3 {
1282
+ margin: 0;
1283
+ font-size: var(--font-size-lg);
1284
+ font-weight: var(--font-weight-semibold);
1285
+ color: var(--surface-overlay-text);
1286
+ flex: 1;
1287
+ }
1288
+
1289
+ /* Close button in header */
1290
+ button[value="cancel"],
1291
+ .dialog-close {
1292
+ background: none;
1293
+ border: none;
1294
+ padding: var(--spacing-2);
1295
+ border-radius: var(--radius-sm);
1296
+ cursor: pointer;
1297
+ color: var(--surface-overlay-icon);
1298
+ transition: background-color var(--transition-fast);
1299
+ display: inline-flex;
1300
+ align-items: center;
1301
+ justify-content: center;
1302
+
1303
+ &:hover {
1304
+ background-color: var(--color-surface-subtle);
1305
+ }
1306
+
1307
+ &:focus-visible {
1308
+ outline: 2px solid var(--color-focus-ring);
1309
+ outline-offset: 2px;
1310
+ }
1311
+ }
1312
+ }
1313
+
1314
+ /* Dialog body - scrollable content */
1315
+ article,
1316
+ form > article,
1317
+ .dialog-body {
1318
+ flex: 1;
1319
+ padding: var(--spacing-6);
1320
+ overflow-y: auto;
1321
+ overflow-x: hidden;
1322
+ }
1323
+
1324
+ /* Dialog footer - actions */
1325
+ footer,
1326
+ form > footer {
1327
+ display: flex;
1328
+ flex-direction: row;
1329
+ gap: var(--spacing-3);
1330
+ justify-content: flex-end;
1331
+ align-items: center;
1332
+ padding: var(--spacing-6);
1333
+ border-top: 1px solid var(--surface-overlay-border);
1334
+ flex-shrink: 0;
1335
+ }
1336
+ }
1337
+
1338
+ /* Dialog size modifiers */
1339
+ dialog.dialog-sm {
1340
+ max-width: min(400px, calc(100vw - var(--spacing-8)));
1341
+ }
1342
+
1343
+ dialog.dialog-lg {
1344
+ max-width: min(800px, calc(100vw - var(--spacing-8)));
1345
+ }
1346
+
1347
+ dialog.dialog-xl {
1348
+ max-width: min(1200px, calc(100vw - var(--spacing-8)));
1349
+ }
1350
+
1351
+ dialog.dialog-full {
1352
+ max-width: calc(100vw - var(--spacing-8));
1353
+ max-height: calc(100vh - var(--spacing-8));
1354
+ }
1355
+
1356
+ /* Mobile responsiveness */
1357
+ @media (max-width: 639px) {
1358
+ dialog {
1359
+ max-width: 100vw;
1360
+ max-height: 100vh;
1361
+ border-radius: 0;
1362
+ top: 50%;
1363
+ transform: translateY(-50%);
1364
+ margin: 0;
1365
+ }
1366
+
1367
+ dialog header,
1368
+ dialog form > header,
1369
+ dialog article,
1370
+ dialog form > article,
1371
+ dialog footer,
1372
+ dialog form > footer {
1373
+ padding: var(--spacing-4);
1374
+ }
1375
+ }
1376
+
1377
+ /* Reduced motion support */
1378
+ @media (prefers-reduced-motion: reduce) {
1379
+ dialog,
1380
+ dialog::backdrop {
1381
+ transition-duration: 0.01s !important;
1382
+ }
1383
+ }
1384
+
1385
+
1386
+
1387
+ /* Accordion (details/summary) */
1388
+
1389
+ .accordion {
1390
+ --_acc-radius: var(--radius-md);
1391
+ --_acc-border: 1px solid var(--color-border);
1392
+ --_acc-bg: var(--color-surface-base);
1393
+
1394
+ details {
1395
+ border: var(--_acc-border);
1396
+ border-radius: var(--_acc-radius);
1397
+ background: var(--_acc-bg);
1398
+ margin: 0 0 var(--spacing-3) 0;
1399
+
1400
+ &[open] {
1401
+ & > summary::after {
1402
+ transform: rotate(45deg);
1403
+ }
1404
+
1405
+ &::details-content {
1406
+ block-size: auto;
1407
+ }
1408
+ }
1409
+
1410
+ /* Modern approach: animate block-size with ::details-content */
1411
+ &::details-content {
1412
+ block-size: 0;
1413
+ overflow: hidden;
1414
+ transition: block-size var(--transition-normal) ease, content-visibility var(--transition-normal);
1415
+ transition-behavior: allow-discrete;
1416
+ }
1417
+
1418
+ /* Content padding (works for both approaches) */
1419
+ & > :not(summary) > * {
1420
+ padding-inline: var(--spacing-4);
1421
+ padding-block: var(--spacing-3);
1422
+ }
1423
+ }
1424
+
1425
+ summary {
1426
+ cursor: pointer;
1427
+ padding: var(--spacing-3) var(--spacing-4);
1428
+ list-style: none;
1429
+ outline: none;
1430
+ display: flex;
1431
+ align-items: center;
1432
+ gap: var(--spacing-2);
1433
+
1434
+ &::-webkit-details-marker {
1435
+ display: none;
1436
+ }
1437
+
1438
+ /* Chevron indicator */
1439
+ &::after {
1440
+ content: "";
1441
+ margin-inline-start: auto;
1442
+ inline-size: 0.7em;
1443
+ block-size: 0.7em;
1444
+ border-inline-end: 2px solid currentColor;
1445
+ border-block-end: 2px solid currentColor;
1446
+ transform: rotate(-45deg);
1447
+ transition: transform var(--transition-normal);
1448
+ }
1449
+ }
1450
+ }
1451
+
1452
+ /* Fallback: grid trick for browsers without ::details-content support */
1453
+ @supports not selector(::details-content) {
1454
+ .accordion details {
1455
+ & > :not(summary) {
1456
+ display: grid;
1457
+ grid-template-rows: 0fr;
1458
+ transition: grid-template-rows var(--transition-normal) ease;
1459
+ overflow: hidden;
1460
+
1461
+ & > * {
1462
+ min-block-size: 0;
1463
+ }
1464
+ }
1465
+
1466
+ &[open] > :not(summary) {
1467
+ grid-template-rows: 1fr;
1468
+ }
1469
+ }
1470
+ }
1471
+
1472
+
1473
+ /* Dropdown Component */
1474
+
1475
+ /* Basic dropdown host */
1476
+ nav[data-dropdown] {
1477
+ position: relative;
1478
+ display: inline-block;
1479
+ padding: 0;
1480
+
1481
+ menu {
1482
+ position: absolute;
1483
+ list-style: none;
1484
+ padding: var(--spacing-2);
1485
+ margin: 0;
1486
+ background: var(--color-surface-overlay);
1487
+ border: 1px solid var(--color-border);
1488
+ border-radius: var(--radius-md);
1489
+ box-shadow: var(--shadow-lg);
1490
+ top: 100%;
1491
+ bottom: auto;
1492
+ left: 0;
1493
+ right: auto;
1494
+ margin-top: var(--spacing-2);
1495
+ --dropdown-transition-duration: var(--transition-fast, 160ms);
1496
+ min-width: max(100%, var(--dropdown-min-width, 12rem));
1497
+ width: max-content;
1498
+ opacity: 0;
1499
+ scale: 0.95;
1500
+ visibility: hidden;
1501
+ display: none;
1502
+ pointer-events: none;
1503
+ transform-origin: top center;
1504
+ z-index: var(--z-dropdown, 1050);
1505
+ max-height: min(60vh, 24rem);
1506
+ overflow-y: auto;
1507
+ transition:
1508
+ opacity var(--dropdown-transition-duration) ease,
1509
+ scale var(--dropdown-transition-duration) ease,
1510
+ visibility 0s linear var(--dropdown-transition-duration),
1511
+ display 0s linear var(--dropdown-transition-duration);
1512
+ transition-behavior: allow-discrete;
1513
+ }
1514
+
1515
+ menu[aria-hidden="false"] {
1516
+ display: block;
1517
+ opacity: 1;
1518
+ scale: 1;
1519
+ visibility: visible;
1520
+ pointer-events: auto;
1521
+ transition:
1522
+ opacity var(--dropdown-transition-duration) ease,
1523
+ scale var(--dropdown-transition-duration) ease,
1524
+ visibility 0s linear 0s,
1525
+ display 0s linear 0s;
1526
+ }
1527
+
1528
+ li {
1529
+ padding: var(--spacing-1) 0;
1530
+
1531
+ & + li {
1532
+ border-top: 1px solid var(--color-border);
1533
+ margin-top: var(--spacing-2);
1534
+ }
1535
+
1536
+ &:has(> hr) {
1537
+ border-top: none;
1538
+ margin-top: 0;
1539
+ padding: 0;
1540
+
1541
+ & + li {
1542
+ border-top: none;
1543
+ margin-top: 0;
1544
+ }
1545
+ }
1546
+
1547
+ & > hr {
1548
+ border: none;
1549
+ border-top: 3px solid var(--color-border);
1550
+ margin: var(--spacing-2) 0;
1551
+ }
1552
+ }
1553
+
1554
+ a {
1555
+ display: flex;
1556
+ color: var(--color-text-primary);
1557
+ text-decoration: none;
1558
+ align-items: center;
1559
+ gap: var(--spacing-2);
1560
+
1561
+ &.danger {
1562
+ color: var(--color-danger-600);
1563
+ }
1564
+ }
1565
+
1566
+ &.align-right,
1567
+ &[data-align="right"],
1568
+ &[data-align="end"],
1569
+ &[data-dropdown-align="right"],
1570
+ &[data-dropdown-align="end"] {
1571
+ menu {
1572
+ left: auto;
1573
+ right: 0;
1574
+ }
1575
+ }
1576
+
1577
+ &[data-mode="up"],
1578
+ &[data-dropdown-direction="up"] {
1579
+ menu {
1580
+ top: auto;
1581
+ bottom: 100%;
1582
+ margin-top: 0;
1583
+ margin-bottom: var(--spacing-2);
1584
+ transform-origin: bottom center;
1585
+ }
1586
+ }
1587
+
1588
+ &[data-mode="down"],
1589
+ &[data-dropdown-direction="down"] {
1590
+ menu {
1591
+ top: 100%;
1592
+ bottom: auto;
1593
+ margin-top: var(--spacing-2);
1594
+ margin-bottom: 0;
1595
+ transform-origin: top center;
1596
+ }
1597
+ }
1598
+
1599
+ &[data-mode="auto"] menu {
1600
+ top: 100%;
1601
+ bottom: auto;
1602
+ }
1603
+
1604
+ @media (prefers-reduced-motion: reduce) {
1605
+ menu {
1606
+ transition-duration: 0.01s !important;
1607
+ }
1608
+ }
1609
+ }
1610
+
1611
+ @starting-style {
1612
+ nav[data-dropdown] menu[aria-hidden="false"] {
1613
+ opacity: 0;
1614
+ scale: 0.95;
1615
+ }
1616
+ }
1617
+
1618
+
1619
+ /* Tab Strip Component */
1620
+
1621
+ /* Tab navigation */
1622
+
1623
+ pds-tabstrip {
1624
+ margin-top: var(--spacing-6);
1625
+
1626
+ & > nav {
1627
+ display: flex;
1628
+ gap: var(--spacing-1);
1629
+ border-bottom: 2px solid var(--color-border);
1630
+ margin-bottom: var(--spacing-6);
1631
+ position: relative;
1632
+ overflow-x: auto;
1633
+ overflow-y: hidden;
1634
+ scrollbar-width: none; /* Firefox */
1635
+ -ms-overflow-style: none; /* IE/Edge */
1636
+
1637
+ &::-webkit-scrollbar {
1638
+ display: none; /* Chrome/Safari */
1639
+ }
1640
+
1641
+ /* Tab links */
1642
+ & > a {
1643
+ position: relative;
1644
+ display: inline-flex;
1645
+ align-items: center;
1646
+ gap: var(--spacing-2);
1647
+ padding: var(--spacing-3) var(--spacing-4);
1648
+ font-family: var(--font-family-body);
1649
+ font-size: var(--font-size-base);
1650
+ font-weight: var(--font-weight-medium);
1651
+ color: var(--color-text-secondary);
1652
+ text-decoration: none;
1653
+ white-space: nowrap;
1654
+ border: none;
1655
+ background: transparent;
1656
+ cursor: pointer;
1657
+ transition: color var(--transition-fast);
1658
+ border-bottom: 2px solid transparent;
1659
+ margin-bottom: -2px; /* Overlap the nav border */
1660
+
1661
+ &:hover {
1662
+ color: var(--color-text-primary);
1663
+ background-color: var(--color-surface-hover);
1664
+ }
1665
+
1666
+ &:focus-visible {
1667
+ outline: var(--focus-ring-width, 2px) solid var(--color-primary-500);
1668
+ outline-offset: -2px;
1669
+ border-radius: var(--radius-sm);
1670
+ z-index: 1;
1671
+ }
1672
+
1673
+ /* Active tab */
1674
+ &[aria-current="page"] {
1675
+ color: var(--color-primary-600);
1676
+ font-weight: var(--font-weight-semibold);
1677
+ border-bottom-color: var(--color-primary-600);
1678
+
1679
+ &:hover {
1680
+ color: var(--color-primary-700);
1681
+ border-bottom-color: var(--color-primary-700);
1682
+ background-color: var(--color-primary-50);
1683
+ }
1684
+ }
1685
+ }
1686
+ }
1687
+
1688
+ /* Tab panel */
1689
+ & > pds-tabpanel {
1690
+ display: block;
1691
+ margin-top: var(--spacing-4);
1692
+
1693
+ &[data-tabpanel] {
1694
+ animation: tabFadeIn var(--transition-normal) ease-out;
1695
+ padding: var(--spacing-4) 0;
1696
+
1697
+ &[hidden] {
1698
+ display: none;
1699
+ }
1700
+ }
1701
+ }
1702
+ }
1703
+
1704
+ @keyframes tabFadeIn {
1705
+ from {
1706
+ opacity: 0;
1707
+ transform: translateY(8px);
1708
+ }
1709
+ to {
1710
+ opacity: 1;
1711
+ transform: translateY(0);
1712
+ }
1713
+ }
1714
+
1715
+ /* Mobile responsive */
1716
+ @media (max-width: 639px) {
1717
+ pds-tabstrip > nav {
1718
+ gap: var(--spacing-1);
1719
+ }
1720
+
1721
+ pds-tabstrip > nav > a {
1722
+ padding: var(--spacing-2) var(--spacing-3);
1723
+ font-size: var(--font-size-sm);
1724
+ }
1725
+
1726
+ pds-tabstrip > pds-tabpanel[data-tabpanel] {
1727
+ padding: var(--spacing-3) 0;
1728
+ }
1729
+ }
1730
+
1731
+
1732
+
1733
+ /* Table Styles - Mobile First */
1734
+
1735
+ table {
1736
+ width: 100%;
1737
+ border-collapse: collapse;
1738
+ margin: 0 0 var(--spacing-6) 0;
1739
+ background-color: var(--color-surface-base);
1740
+ border-radius: var(--radius-md);
1741
+ overflow: hidden;
1742
+ font-size: var(--font-size-sm);
1743
+
1744
+ @media (min-width: 640px) {
1745
+ font-size: var(--font-size-base);
1746
+ }
1747
+ }
1748
+
1749
+ .table-responsive {
1750
+ @media (max-width: 639px) {
1751
+ overflow-x: auto;
1752
+ -webkit-overflow-scrolling: touch;
1753
+ margin: 0 0 var(--spacing-6) 0;
1754
+
1755
+ table {
1756
+ min-width: 600px;
1757
+ margin: 0;
1758
+ }
1759
+ }
1760
+ }
1761
+
1762
+ thead {
1763
+ background-color: var(--color-surface-subtle);
1764
+ }
1765
+
1766
+ th {
1767
+ padding: var(--spacing-3) var(--spacing-4);
1768
+ text-align: left;
1769
+ font-weight: var(--font-weight-semibold);
1770
+ color: var(--color-text-primary);
1771
+ border-bottom: 2px solid var(--color-border);
1772
+ }
1773
+
1774
+ td {
1775
+ padding: var(--spacing-3) var(--spacing-4);
1776
+ color: var(--color-text-secondary);
1777
+ border-bottom: 1px solid var(--color-border);
1778
+ }
1779
+
1780
+ tbody {
1781
+ tr {
1782
+ transition: background-color var(--transition-fast);
1783
+
1784
+ &:hover {
1785
+ background-color: var(--color-surface-subtle);
1786
+ }
1787
+
1788
+ &:last-child td {
1789
+ border-bottom: none;
1790
+ }
1791
+ }
1792
+ }
1793
+
1794
+ .table-striped {
1795
+ tbody tr:nth-child(even) {
1796
+ background-color: var(--color-surface-subtle);
1797
+ }
1798
+ }
1799
+
1800
+ .table-bordered {
1801
+ border: 1px solid var(--color-border);
1802
+
1803
+ th, td {
1804
+ border: 1px solid var(--color-border);
1805
+ }
1806
+ }
1807
+
1808
+ .table-compact {
1809
+ th, td {
1810
+ padding: var(--spacing-2) var(--spacing-3);
1811
+ }
1812
+ }
1813
+
1814
+
1815
+
1816
+ /* Card component */
1817
+
1818
+ .card {
1819
+ background: var(--color-surface-base);
1820
+ border-radius: var(--radius-md);
1821
+ padding: var(--spacing-4);
1822
+
1823
+ &-elevated {
1824
+ background: var(--color-surface-elevated);
1825
+ box-shadow: var(--shadow-md);
1826
+ }
1827
+
1828
+ &-outlined,
1829
+ &-basic {
1830
+ background: var(--color-surface-base);
1831
+ border: 1px solid var(--color-border);
1832
+ }
1833
+
1834
+ &-interactive:hover {
1835
+ transform: translateY(-2px);
1836
+ box-shadow: var(--shadow-lg);
1837
+ transition: transform var(--transition-fast), box-shadow var(--transition-fast);
1838
+ }
1839
+ }
1840
+
1841
+ /* Custom Scrollbars */
1842
+
1843
+ ::-webkit-scrollbar {
1844
+ width: 12px;
1845
+ height: 12px;
1846
+
1847
+ &-track {
1848
+ background: transparent;
1849
+ }
1850
+
1851
+ &-thumb {
1852
+ background: var(--color-secondary-300);
1853
+ border-radius: var(--radius-full);
1854
+ border: 3px solid transparent;
1855
+ background-clip: padding-box;
1856
+ transition: background-color var(--transition-fast);
1857
+
1858
+ &:hover {
1859
+ background: var(--color-secondary-400);
1860
+ border: 2px solid transparent;
1861
+ background-clip: padding-box;
1862
+ }
1863
+
1864
+ &:active {
1865
+ background: var(--color-secondary-500);
1866
+ border: 2px solid transparent;
1867
+ background-clip: padding-box;
1868
+ }
1869
+
1870
+ @media (prefers-color-scheme: dark) {
1871
+ background: var(--color-secondary-600);
1872
+
1873
+ &:hover {
1874
+ background: var(--color-secondary-500);
1875
+ }
1876
+
1877
+ &:active {
1878
+ background: var(--color-secondary-400);
1879
+ }
1880
+ }
1881
+ }
1882
+ }
1883
+
1884
+ * {
1885
+ scrollbar-width: thin;
1886
+ scrollbar-color: var(--color-secondary-300) transparent;
1887
+
1888
+ @media (prefers-color-scheme: dark) {
1889
+ scrollbar-color: var(--color-secondary-600) transparent;
1890
+ }
1891
+ }
1892
+
1893
+ /* Hover effect for scrollable containers */
1894
+ *:hover {
1895
+ scrollbar-color: var(--color-secondary-400) transparent;
1896
+ }
1897
+
1898
+ @media (prefers-color-scheme: dark) {
1899
+ *:hover {
1900
+ scrollbar-color: var(--color-secondary-500) transparent;
1901
+ }
1902
+ }
1903
+
1904
+
1905
+
1906
+ /* Alert dark mode adjustments */
1907
+ html[data-theme="dark"] .alert-success {
1908
+ background-color: var(--color-success-50);
1909
+ border-color: var(--color-success-500);
1910
+ color: var(--color-success-900);
1911
+ }
1912
+
1913
+ html[data-theme="dark"] .alert-info {
1914
+ background-color: var(--color-info-50);
1915
+ border-color: var(--color-info-500);
1916
+ color: var(--color-info-900);
1917
+ }
1918
+
1919
+ html[data-theme="dark"] .alert-warning {
1920
+ background-color: var(--color-warning-50);
1921
+ border-color: var(--color-warning-500);
1922
+ color: var(--color-warning-900);
1923
+ }
1924
+
1925
+ html[data-theme="dark"] .alert-danger,
1926
+ html[data-theme="dark"] .alert-error {
1927
+ background-color: var(--color-danger-50);
1928
+ border-color: var(--color-danger-500);
1929
+ color: var(--color-danger-900);
1930
+ }
1931
+
1932
+ /* Dim images in dark mode */
1933
+ html[data-theme="dark"] img,
1934
+ html[data-theme="dark"] video {
1935
+ opacity: 0.8;
1936
+ transition: opacity var(--transition-normal);
1937
+ }
1938
+
1939
+ html[data-theme="dark"] img:hover,
1940
+ html[data-theme="dark"] video:hover {
1941
+ opacity: 1;
1942
+ }
1943
+
1944
+ }