@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,1533 @@
1
+ // Pure Design System - utilities
2
+ // Auto-generated - do not edit directly
3
+
4
+ export const utilities = new CSSStyleSheet();
5
+ utilities.replaceSync(`@layer utilities {
6
+
7
+ /* Icon System */
8
+
9
+ pds-icon {
10
+ display: inline-flex;
11
+ align-items: center;
12
+ justify-content: center;
13
+ flex-shrink: 0;
14
+ vertical-align: middle;
15
+ pointer-events: none;
16
+ }
17
+
18
+ /* Icon size utilities */
19
+ .icon-xs,
20
+ pds-icon[size="xs"] {
21
+ width: var(--icon-size-xs);
22
+ height: var(--icon-size-xs);
23
+ }
24
+
25
+ .icon-sm,
26
+ pds-icon[size="sm"] {
27
+ width: var(--icon-size-sm);
28
+ height: var(--icon-size-sm);
29
+ }
30
+
31
+ .icon-md,
32
+ pds-icon[size="md"] {
33
+ width: var(--icon-size-md);
34
+ height: var(--icon-size-md);
35
+ }
36
+
37
+ .icon-lg,
38
+ pds-icon[size="lg"] {
39
+ width: var(--icon-size-lg);
40
+ height: var(--icon-size-lg);
41
+ }
42
+
43
+ .icon-xl,
44
+ pds-icon[size="xl"] {
45
+ width: var(--icon-size-xl);
46
+ height: var(--icon-size-xl);
47
+ }
48
+
49
+ .icon-2xl,
50
+ pds-icon[size="2xl"] {
51
+ width: var(--icon-size-2xl);
52
+ height: var(--icon-size-2xl);
53
+ }
54
+
55
+ /* Icon color utilities */
56
+ .icon-primary,
57
+ pds-icon.primary {
58
+ color: var(--color-primary-600);
59
+ }
60
+
61
+ .icon-secondary,
62
+ pds-icon.secondary {
63
+ color: var(--color-secondary-600);
64
+ }
65
+
66
+ .icon-accent,
67
+ pds-icon.accent {
68
+ color: var(--color-accent-600);
69
+ }
70
+
71
+ .icon-success,
72
+ pds-icon.success {
73
+ color: var(--color-success-600);
74
+ }
75
+
76
+ .icon-warning,
77
+ pds-icon.warning {
78
+ color: var(--color-warning-600);
79
+ }
80
+
81
+ .icon-danger,
82
+ pds-icon.danger {
83
+ color: var(--color-danger-600);
84
+ }
85
+
86
+ .icon-info,
87
+ pds-icon.info {
88
+ color: var(--color-info-600);
89
+ }
90
+
91
+ .icon-muted,
92
+ pds-icon.muted {
93
+ color: var(--color-text-muted);
94
+ }
95
+
96
+ .icon-subtle,
97
+ pds-icon.subtle {
98
+ color: var(--color-text-subtle);
99
+ }
100
+
101
+ /* Icon with text combinations */
102
+ .icon-text {
103
+ display: inline-flex;
104
+ align-items: center;
105
+ gap: var(--spacing-2);
106
+ }
107
+
108
+ .icon-text-start {
109
+ flex-direction: row;
110
+ }
111
+
112
+ .icon-text-end {
113
+ flex-direction: row-reverse;
114
+ }
115
+
116
+ /* Button icon utilities */
117
+ button, a {
118
+ pds-icon {
119
+ flex-shrink: 0;
120
+ }
121
+
122
+ &.icon-only {
123
+ padding: var(--spacing-2);
124
+ min-width: 44px;
125
+ width: 44px;
126
+ height: 44px;
127
+ display: inline-flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ }
131
+ }
132
+
133
+ /* Icon in inputs */
134
+ .input-icon {
135
+ position: relative;
136
+ display: flex;
137
+ align-items: center;
138
+
139
+ pds-icon {
140
+ position: absolute;
141
+ left: var(--spacing-3);
142
+ color: var(--color-text-muted);
143
+ pointer-events: none;
144
+ width: var(--icon-size-md);
145
+ height: var(--icon-size-md);
146
+ }
147
+
148
+ input {
149
+ padding-left: calc(var(--icon-size-md) + var(--spacing-6));
150
+ width: 100%;
151
+ }
152
+ }
153
+
154
+ .input-icon-end {
155
+ position: relative;
156
+ display: flex;
157
+ align-items: center;
158
+
159
+ pds-icon {
160
+ position: absolute;
161
+ left: unset;
162
+ right: var(--spacing-3);
163
+ color: var(--color-text-muted);
164
+ pointer-events: none;
165
+ width: var(--icon-size-md);
166
+ height: var(--icon-size-md);
167
+ }
168
+
169
+ input {
170
+ padding-left: var(--spacing-4);
171
+ padding-right: calc(var(--icon-size-md) + var(--spacing-6));
172
+ width: 100%;
173
+ }
174
+ }
175
+
176
+
177
+
178
+
179
+ /* ============================================================================
180
+ Layout Utilities
181
+ Modern grid and flex system for building responsive layouts
182
+ ============================================================================ */
183
+
184
+ /* Container */
185
+ .container {
186
+ display: block;
187
+ width: 100%;
188
+ max-width: 1400px;
189
+ margin: 0 auto;
190
+ padding: var(--spacing-6);
191
+ }
192
+
193
+ /* Grid System */
194
+ .grid {
195
+ display: grid;
196
+ gap: var(--spacing-4);
197
+ }
198
+
199
+ .grid-cols-1 { grid-template-columns: repeat(1, 1fr); }
200
+ .grid-cols-2 { grid-template-columns: repeat(2, 1fr); }
201
+ .grid-cols-3 { grid-template-columns: repeat(3, 1fr); }
202
+ .grid-cols-4 { grid-template-columns: repeat(4, 1fr); }
203
+ .grid-cols-6 { grid-template-columns: repeat(6, 1fr); }
204
+
205
+ /* Auto-fit grids (responsive) */
206
+ .grid-auto-sm { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
207
+ .grid-auto-md { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
208
+ .grid-auto-lg { grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); }
209
+ .grid-auto-xl { grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); }
210
+
211
+ /* Gap utilities */
212
+ .gap-0 { gap: 0; }
213
+ .gap-xs { gap: var(--spacing-1); }
214
+ .gap-sm { gap: var(--spacing-2); }
215
+ .gap-md { gap: var(--spacing-4); }
216
+ .gap-lg { gap: var(--spacing-6); }
217
+ .gap-xl { gap: var(--spacing-8); }
218
+
219
+
220
+ /* Flexbox System */
221
+ .flex {
222
+ display: flex;
223
+ }
224
+
225
+ .flex-wrap {
226
+ flex-wrap: wrap;
227
+ }
228
+
229
+ .flex-col {
230
+ flex-direction: column;
231
+ }
232
+
233
+ .flex-row {
234
+ flex-direction: row;
235
+ }
236
+
237
+ /* Flex alignment */
238
+ .items-start { align-items: flex-start; }
239
+ .items-center { align-items: center; }
240
+ .items-end { align-items: flex-end; }
241
+ .items-stretch { align-items: stretch; }
242
+ .items-baseline { align-items: baseline; }
243
+
244
+ .justify-start { justify-content: flex-start; }
245
+ .justify-center { justify-content: center; }
246
+ .justify-end { justify-content: flex-end; }
247
+ .justify-between { justify-content: space-between; }
248
+ .justify-around { justify-content: space-around; }
249
+ .justify-evenly { justify-content: space-evenly; }
250
+
251
+ /* Responsive helpers */
252
+ @media (max-width: 767px) {
253
+ .mobile-stack { flex-direction: column; }
254
+ .mobile-stack > * { width: 100%; }
255
+ }
256
+
257
+ /* ============================================================================
258
+ Backdrop Utilities
259
+ Reusable backdrop layer for modal components (dialogs, drawers, overlays)
260
+ ============================================================================ */
261
+
262
+ /* Base backdrop class for modal overlays */
263
+ .backdrop {
264
+ position: fixed;
265
+ inset: 0;
266
+ background: var(--backdrop-bg);
267
+ backdrop-filter: var(--backdrop-filter);
268
+ opacity: 0;
269
+ pointer-events: none;
270
+ transition: opacity 0.2s ease;
271
+ z-index: var(--z-modal, 1040);
272
+
273
+ &.active {
274
+ opacity: var(--backdrop-opacity, 1);
275
+ pointer-events: auto;
276
+ }
277
+
278
+ /* Backdrop variants */
279
+ &-light {
280
+ --backdrop-bg: linear-gradient(135deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.2));
281
+ --backdrop-brightness: 1.1;
282
+ }
283
+
284
+ &-dark {
285
+ --backdrop-bg: linear-gradient(135deg, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.5));
286
+ --backdrop-brightness: 0.6;
287
+ }
288
+
289
+ &-blur-sm {
290
+ --backdrop-blur: 5px;
291
+ }
292
+
293
+ &-blur-md {
294
+ --backdrop-blur: 10px;
295
+ }
296
+
297
+ &-blur-lg {
298
+ --backdrop-blur: 20px;
299
+ }
300
+ }
301
+
302
+
303
+ /* Optional utilities/features controlled by config options */
304
+ /* - Body background mesh rule (applies one of the generated mesh vars) */
305
+ /* - Liquid glass utility class */
306
+ /* Optional background mesh applied from config */
307
+ body {
308
+ background: var(--background-mesh-04);
309
+ background-attachment: fixed;
310
+ }
311
+ /* Liquid glass utility (opt-in via options.liquidGlassEffects) */
312
+ .liquid-glass {
313
+ border-radius: var(--radius-lg);
314
+ /* Subtle translucent fill blended with surface */
315
+ background: color-mix(in oklab, var(--color-surface-subtle) 45%, transparent);
316
+
317
+ background-image: linear-gradient(
318
+ 135deg,
319
+ rgba(255,255,255,0.35),
320
+ rgba(255,255,255,0.12)
321
+ );
322
+ /* Frosted glass blur + saturation */
323
+ -webkit-backdrop-filter: blur(12px) saturate(140%);
324
+ backdrop-filter: blur(12px) saturate(140%);
325
+ /* Soft inner highlight and outer depth */
326
+ box-shadow:
327
+ inset 0 1px 0 rgba(255,255,255,0.6),
328
+ inset 0 -40px 80px rgba(255,255,255,0.12),
329
+ 0 10px 30px rgba(0,0,0,0.10);
330
+ /* Glossy border with slight light and dark edges */
331
+ border: 1px solid color-mix(in oklab, var(--color-primary-500) 22%, transparent);
332
+ outline: 1px solid color-mix(in oklab, #ffffff 18%, transparent);
333
+ outline-offset: -1px;
334
+ }
335
+
336
+ html[data-theme="dark"] .liquid-glass {
337
+ background: color-mix(in oklab, var(--color-surface-inverse) 45%, transparent);
338
+ background-image: linear-gradient(
339
+ 135deg,
340
+ color-mix(in oklab, var(--color-primary-300) 40%, transparent),
341
+ color-mix(in oklab, var(--color-surface-overlay) 48%, transparent)
342
+ );
343
+ box-shadow:
344
+ inset 0 1px 0 rgba(255,255,255,0.12),
345
+ inset 0 -40px 80px rgba(0,0,0,0.55),
346
+ 0 18px 38px rgba(0,0,0,0.65);
347
+ border: 1px solid color-mix(in oklab, var(--color-primary-300) 26%, transparent);
348
+ outline: 1px solid color-mix(in oklab, #ffffff 16%, transparent);
349
+ }
350
+
351
+ /* Fallback when backdrop-filter isn't supported */
352
+ @supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
353
+ .liquid-glass {
354
+ /* Strengthen fill a bit to compensate for lack of blur */
355
+ background: color-mix(in oklab, var(--color-surface-subtle) 70%, rgba(255,255,255,0.4));
356
+ box-shadow:
357
+ inset 0 1px 0 rgba(255,255,255,0.6),
358
+ 0 10px 24px rgba(0,0,0,0.08);
359
+ }
360
+
361
+ html[data-theme="dark"] .liquid-glass {
362
+ background: color-mix(in oklab, var(--color-surface-inverse) 70%, transparent);
363
+ box-shadow:
364
+ inset 0 1px 0 rgba(255,255,255,0.1),
365
+ 0 18px 32px rgba(0,0,0,0.58);
366
+ }
367
+ }
368
+
369
+
370
+ /* ============================================================================
371
+ Border Gradient Utilities
372
+ Card outlines with gradient borders and glow effects
373
+ ============================================================================ */
374
+
375
+
376
+ /* Gradient border utility - premium/promo card style */
377
+ .border-gradient {
378
+ border: var(--border-width-medium) solid transparent;
379
+ background:
380
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
381
+ linear-gradient(var(--gradient-angle, 135deg),
382
+ var(--color-primary-400),
383
+ var(--color-accent-400)
384
+ ) border-box;
385
+ }
386
+
387
+ /* Gradient border variants - different color combinations */
388
+ .border-gradient-primary {
389
+ border: var(--border-width-medium) solid transparent;
390
+ background:
391
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
392
+ linear-gradient(var(--gradient-angle, 135deg),
393
+ var(--color-primary-300),
394
+ var(--color-primary-600)
395
+ ) border-box;
396
+ }
397
+
398
+ .border-gradient-accent {
399
+ border: var(--border-width-medium) solid transparent;
400
+ background:
401
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
402
+ linear-gradient(var(--gradient-angle, 135deg),
403
+ var(--color-accent-300),
404
+ var(--color-accent-600)
405
+ ) border-box;
406
+ }
407
+
408
+ .border-gradient-secondary {
409
+ border: var(--border-width-medium) solid transparent;
410
+ background:
411
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
412
+ linear-gradient(var(--gradient-angle, 135deg),
413
+ var(--color-secondary-300),
414
+ var(--color-secondary-600)
415
+ ) border-box;
416
+ }
417
+
418
+ /* Gradient border with different strengths/thickness */
419
+ .border-gradient-soft {
420
+ border: 1px solid transparent;
421
+ background:
422
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
423
+ linear-gradient(var(--gradient-angle, 135deg),
424
+ var(--color-primary-400),
425
+ var(--color-accent-400)
426
+ ) border-box;
427
+ }
428
+
429
+ .border-gradient-medium {
430
+ border: 2px solid transparent;
431
+ background:
432
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
433
+ linear-gradient(var(--gradient-angle, 135deg),
434
+ var(--color-primary-400),
435
+ var(--color-accent-400)
436
+ ) border-box;
437
+ }
438
+
439
+ .border-gradient-strong {
440
+ border: 3px solid transparent;
441
+ background:
442
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
443
+ linear-gradient(var(--gradient-angle, 135deg),
444
+ var(--color-primary-400),
445
+ var(--color-accent-400)
446
+ ) border-box;
447
+ }
448
+
449
+ /* Glow effect utility - for callouts and active states */
450
+ .border-glow {
451
+ box-shadow: 0 0 12px var(--color-primary-500);
452
+ }
453
+
454
+ .border-glow-sm {
455
+ box-shadow: 0 0 6px var(--color-primary-500);
456
+ }
457
+
458
+ .border-glow-lg {
459
+ box-shadow: 0 0 20px var(--color-primary-500);
460
+ }
461
+
462
+ /* Combined gradient + glow for premium effects */
463
+ .border-gradient-glow {
464
+ border: var(--border-width-medium) solid transparent;
465
+ background:
466
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
467
+ linear-gradient(135deg,
468
+ var(--color-primary-400),
469
+ var(--color-accent-400)
470
+ ) border-box;
471
+ box-shadow: 0 0 12px var(--color-primary-500);
472
+ }
473
+
474
+ /* Semantic glow variants */
475
+ .border-glow-primary {
476
+ box-shadow: 0 0 12px var(--color-primary-500);
477
+ }
478
+
479
+ .border-glow-accent {
480
+ box-shadow: 0 0 12px var(--color-accent-500);
481
+ }
482
+
483
+ .border-glow-success {
484
+ box-shadow: 0 0 12px var(--color-success-500);
485
+ }
486
+
487
+ .border-glow-warning {
488
+ box-shadow: 0 0 12px var(--color-warning-500);
489
+ }
490
+
491
+ .border-glow-danger {
492
+ box-shadow: 0 0 12px var(--color-danger-500);
493
+ }
494
+
495
+
496
+
497
+ /* Surface utilities */
498
+
499
+ .surface {
500
+ background-color: var(--color-surface-base);
501
+ }
502
+
503
+ .surface-subtle {
504
+ background-color: var(--color-surface-subtle);
505
+ }
506
+
507
+ .surface-elevated {
508
+ background-color: var(--color-surface-elevated);
509
+ }
510
+
511
+ .surface-sunken {
512
+ background-color: var(--color-surface-sunken);
513
+ }
514
+
515
+ .surface-overlay {
516
+ background-color: var(--color-surface-overlay);
517
+ }
518
+
519
+ /* Translucent semantic variants */
520
+ .surface-translucent {
521
+ background-color: var(--color-surface-translucent-50);
522
+ }
523
+
524
+ .surface-translucent-25 {
525
+ background-color: var(--color-surface-translucent-25);
526
+ }
527
+
528
+ .surface-translucent-50 {
529
+ background-color: var(--color-surface-translucent-50);
530
+ }
531
+
532
+ .surface-translucent-75 {
533
+ background-color: var(--color-surface-translucent-75);
534
+ }
535
+
536
+ /* Legacy utility retained for backwards compatibility (opinionated overlay) */
537
+ .surface-overlay {
538
+ padding: var(--spacing-4);
539
+ background-color: var(--color-surface-overlay);
540
+ box-shadow: var(--shadow-lg);
541
+ border-radius: var(--radius-md);
542
+ }
543
+
544
+
545
+ /* Inverse surface (dark) using PDS tokens; text/icons inherit currentColor */
546
+ .surface-inverse {
547
+ background-color: var(--color-surface-inverse);
548
+ /* Ensure foregrounds inside use the correct smart-surface tokens */
549
+ color: var(--surface-inverse-text);
550
+ --color-text-primary: var(--surface-inverse-text);
551
+ --color-text-secondary: var(--surface-inverse-text-secondary);
552
+ --color-text-muted: var(--surface-inverse-text-muted);
553
+ /* Ensure code/pre and other muted surfaces have contrast on inverse */
554
+ --color-surface-muted: rgba(255, 255, 255, 0.08);
555
+ /* Optional: adjust borders/shadows if utilities/components read these */
556
+ --color-border: var(--surface-inverse-border);
557
+
558
+ pds-icon {
559
+ color: var(--surface-inverse-icon);
560
+ }
561
+ }
562
+
563
+ /* Shadow utilities */
564
+ .shadow-sm {
565
+ box-shadow: var(--shadow-sm);
566
+ }
567
+
568
+ .shadow-base, .shadow {
569
+ box-shadow: var(--shadow-base);
570
+ }
571
+
572
+ .shadow-md {
573
+ box-shadow: var(--shadow-md);
574
+ }
575
+
576
+ .shadow-lg {
577
+ box-shadow: var(--shadow-lg);
578
+ }
579
+
580
+ .shadow-xl {
581
+ box-shadow: var(--shadow-xl);
582
+ }
583
+
584
+ .shadow-inner {
585
+ box-shadow: var(--shadow-inner);
586
+ }
587
+
588
+ .shadow-none {
589
+ box-shadow: none;
590
+ }
591
+
592
+ .text-muted {
593
+ color: var(--color-text-muted);
594
+ }
595
+
596
+
597
+ /* Media Element Utilities */
598
+
599
+ /* Gallery images */
600
+ .img-gallery {
601
+ width: 100%;
602
+ height: auto;
603
+ aspect-ratio: 1;
604
+ object-fit: cover;
605
+ border-radius: var(--radius-sm);
606
+ }
607
+
608
+ /* Responsive images with different radius sizes */
609
+ .img-rounded-sm { border-radius: var(--radius-sm); }
610
+ .img-rounded-md { border-radius: var(--radius-md); }
611
+ .img-rounded-lg { border-radius: var(--radius-lg); }
612
+ .img-rounded-xl { border-radius: var(--radius-xl); }
613
+ .img-rounded-full { border-radius: var(--radius-full); }
614
+
615
+ /* Inline images */
616
+ .img-inline {
617
+ display: inline;
618
+ vertical-align: middle;
619
+ border-radius: var(--radius-xs);
620
+ margin: 0 var(--spacing-1);
621
+ max-width: 60px;
622
+ height: auto;
623
+ }
624
+
625
+ /* Video specific utilities */
626
+ .video-responsive {
627
+ width: 100%;
628
+ max-width: 600px;
629
+ height: auto;
630
+ border-radius: var(--radius-md);
631
+ }
632
+
633
+ /* Figure utilities */
634
+ .figure-responsive {
635
+ width: 100%;
636
+ height: auto;
637
+ }
638
+
639
+
640
+
641
+ /* Mobile-First Responsive Design */
642
+
643
+ /* Small devices (640px and up) */
644
+ @media (min-width: 640px) {
645
+ .sm\\:grid-cols-2 { grid-template-columns: repeat(2, 1fr); }
646
+ .sm\\:flex-row { flex-direction: row; }
647
+ .sm\\:text-sm { font-size: var(--font-size-sm); }
648
+ .sm\\:p-6 { padding: var(--spacing-6); }
649
+ .sm\\:gap-6 { gap: var(--spacing-6); }
650
+ .sm\\:hidden { display: none; }
651
+ .sm\\:block { display: block; }
652
+ }
653
+
654
+ /* Medium devices (768px and up) */
655
+ @media (min-width: 768px) {
656
+ .md\\:grid-cols-3 { grid-template-columns: repeat(3, 1fr); }
657
+ .md\\:text-lg { font-size: var(--font-size-lg); }
658
+ .md\\:p-8 { padding: var(--spacing-8); }
659
+ .md\\:gap-8 { gap: var(--spacing-8); }
660
+ .md\\:flex-row { flex-direction: row; }
661
+ .md\\:w-1\\/2 { width: 50%; }
662
+ .md\\:w-1\\/3 { width: 33.333333%; }
663
+ .md\\:hidden { display: none; }
664
+ .md\\:block { display: block; }
665
+ }
666
+
667
+ /* Large devices (1024px and up) */
668
+ @media (min-width: 1024px) {
669
+ .lg\\:grid-cols-4 { grid-template-columns: repeat(4, 1fr); }
670
+ .lg\\:text-xl { font-size: var(--font-size-xl); }
671
+ .lg\\:p-12 { padding: var(--spacing-12); }
672
+ .lg\\:gap-12 { gap: var(--spacing-12); }
673
+ .lg\\:w-1\\/4 { width: 25%; }
674
+ .lg\\:hidden { display: none; }
675
+ .lg\\:block { display: block; }
676
+ }
677
+
678
+ /* Touch device optimizations */
679
+ @media (hover: none) and (pointer: coarse) {
680
+ /* Touch devices - larger touch targets for interactive elements */
681
+ button, a, select, textarea,
682
+ input:not([type="radio"]):not([type="checkbox"]) {
683
+ min-height: 44px;
684
+ min-width: 44px;
685
+ }
686
+
687
+ /* Radio and checkbox inputs: keep reasonable size but ensure label tap area is large */
688
+ input[type="radio"],
689
+ input[type="checkbox"] {
690
+ /* Keep native size - labels provide the touch target */
691
+ min-height: unset;
692
+ min-width: unset;
693
+ }
694
+
695
+ /* Ensure labels with radio/checkbox have adequate touch targets */
696
+ /* Exclude button-style fieldsets which already have proper sizing */
697
+ label:has(input[type="radio"]):not(fieldset.buttons label),
698
+ label:has(input[type="checkbox"]):not(fieldset.buttons label),
699
+ fieldset[role="radiogroup"]:not(.buttons) label,
700
+ fieldset[role="group"]:not(.buttons) label {
701
+ min-height: 44px;
702
+ display: inline-flex;
703
+ align-items: center;
704
+ padding: var(--spacing-2) 0;
705
+ }
706
+
707
+ /* Disable hover effects
708
+ on touch devices */
709
+ .card {
710
+ &:hover {
711
+ box-shadow: var(--shadow-base);
712
+ }
713
+ }
714
+
715
+ a {
716
+ &:hover {
717
+ color: var(--color-primary-600);
718
+ }
719
+ }
720
+ }
721
+
722
+ /* Reduced motion */
723
+ @media (prefers-reduced-motion: reduce) {
724
+ *, *::before, *::after {
725
+ animation-duration: 0.01ms !important;
726
+ animation-iteration-count: 1 !important;
727
+ transition-duration: 0.01ms !important;
728
+ scroll-behavior: auto !important;
729
+ }
730
+ }
731
+
732
+ /* High contrast mode */
733
+ @media (prefers-contrast: high) {
734
+ :root {
735
+ --color-primary-600: #0000ff;
736
+ --color-primary-700: #0000cc;
737
+ }
738
+
739
+ button, input, textarea, select {
740
+ border-width: 2px;
741
+ }
742
+ }
743
+
744
+ /* Print styles */
745
+ @media print {
746
+ *, *::before, *::after {
747
+ background: transparent !important;
748
+ color: black !important;
749
+ box-shadow: none !important;
750
+ }
751
+
752
+ a, a:visited {
753
+ text-decoration: underline;
754
+ }
755
+
756
+ button {
757
+ display: none;
758
+ }
759
+
760
+ .mobile-hidden, .desktop-hidden {
761
+ display: block !important;
762
+ }
763
+ }
764
+
765
+
766
+
767
+ }
768
+ `);
769
+
770
+ export const utilitiesCSS = `@layer utilities {
771
+
772
+ /* Icon System */
773
+
774
+ pds-icon {
775
+ display: inline-flex;
776
+ align-items: center;
777
+ justify-content: center;
778
+ flex-shrink: 0;
779
+ vertical-align: middle;
780
+ pointer-events: none;
781
+ }
782
+
783
+ /* Icon size utilities */
784
+ .icon-xs,
785
+ pds-icon[size="xs"] {
786
+ width: var(--icon-size-xs);
787
+ height: var(--icon-size-xs);
788
+ }
789
+
790
+ .icon-sm,
791
+ pds-icon[size="sm"] {
792
+ width: var(--icon-size-sm);
793
+ height: var(--icon-size-sm);
794
+ }
795
+
796
+ .icon-md,
797
+ pds-icon[size="md"] {
798
+ width: var(--icon-size-md);
799
+ height: var(--icon-size-md);
800
+ }
801
+
802
+ .icon-lg,
803
+ pds-icon[size="lg"] {
804
+ width: var(--icon-size-lg);
805
+ height: var(--icon-size-lg);
806
+ }
807
+
808
+ .icon-xl,
809
+ pds-icon[size="xl"] {
810
+ width: var(--icon-size-xl);
811
+ height: var(--icon-size-xl);
812
+ }
813
+
814
+ .icon-2xl,
815
+ pds-icon[size="2xl"] {
816
+ width: var(--icon-size-2xl);
817
+ height: var(--icon-size-2xl);
818
+ }
819
+
820
+ /* Icon color utilities */
821
+ .icon-primary,
822
+ pds-icon.primary {
823
+ color: var(--color-primary-600);
824
+ }
825
+
826
+ .icon-secondary,
827
+ pds-icon.secondary {
828
+ color: var(--color-secondary-600);
829
+ }
830
+
831
+ .icon-accent,
832
+ pds-icon.accent {
833
+ color: var(--color-accent-600);
834
+ }
835
+
836
+ .icon-success,
837
+ pds-icon.success {
838
+ color: var(--color-success-600);
839
+ }
840
+
841
+ .icon-warning,
842
+ pds-icon.warning {
843
+ color: var(--color-warning-600);
844
+ }
845
+
846
+ .icon-danger,
847
+ pds-icon.danger {
848
+ color: var(--color-danger-600);
849
+ }
850
+
851
+ .icon-info,
852
+ pds-icon.info {
853
+ color: var(--color-info-600);
854
+ }
855
+
856
+ .icon-muted,
857
+ pds-icon.muted {
858
+ color: var(--color-text-muted);
859
+ }
860
+
861
+ .icon-subtle,
862
+ pds-icon.subtle {
863
+ color: var(--color-text-subtle);
864
+ }
865
+
866
+ /* Icon with text combinations */
867
+ .icon-text {
868
+ display: inline-flex;
869
+ align-items: center;
870
+ gap: var(--spacing-2);
871
+ }
872
+
873
+ .icon-text-start {
874
+ flex-direction: row;
875
+ }
876
+
877
+ .icon-text-end {
878
+ flex-direction: row-reverse;
879
+ }
880
+
881
+ /* Button icon utilities */
882
+ button, a {
883
+ pds-icon {
884
+ flex-shrink: 0;
885
+ }
886
+
887
+ &.icon-only {
888
+ padding: var(--spacing-2);
889
+ min-width: 44px;
890
+ width: 44px;
891
+ height: 44px;
892
+ display: inline-flex;
893
+ align-items: center;
894
+ justify-content: center;
895
+ }
896
+ }
897
+
898
+ /* Icon in inputs */
899
+ .input-icon {
900
+ position: relative;
901
+ display: flex;
902
+ align-items: center;
903
+
904
+ pds-icon {
905
+ position: absolute;
906
+ left: var(--spacing-3);
907
+ color: var(--color-text-muted);
908
+ pointer-events: none;
909
+ width: var(--icon-size-md);
910
+ height: var(--icon-size-md);
911
+ }
912
+
913
+ input {
914
+ padding-left: calc(var(--icon-size-md) + var(--spacing-6));
915
+ width: 100%;
916
+ }
917
+ }
918
+
919
+ .input-icon-end {
920
+ position: relative;
921
+ display: flex;
922
+ align-items: center;
923
+
924
+ pds-icon {
925
+ position: absolute;
926
+ left: unset;
927
+ right: var(--spacing-3);
928
+ color: var(--color-text-muted);
929
+ pointer-events: none;
930
+ width: var(--icon-size-md);
931
+ height: var(--icon-size-md);
932
+ }
933
+
934
+ input {
935
+ padding-left: var(--spacing-4);
936
+ padding-right: calc(var(--icon-size-md) + var(--spacing-6));
937
+ width: 100%;
938
+ }
939
+ }
940
+
941
+
942
+
943
+
944
+ /* ============================================================================
945
+ Layout Utilities
946
+ Modern grid and flex system for building responsive layouts
947
+ ============================================================================ */
948
+
949
+ /* Container */
950
+ .container {
951
+ display: block;
952
+ width: 100%;
953
+ max-width: 1400px;
954
+ margin: 0 auto;
955
+ padding: var(--spacing-6);
956
+ }
957
+
958
+ /* Grid System */
959
+ .grid {
960
+ display: grid;
961
+ gap: var(--spacing-4);
962
+ }
963
+
964
+ .grid-cols-1 { grid-template-columns: repeat(1, 1fr); }
965
+ .grid-cols-2 { grid-template-columns: repeat(2, 1fr); }
966
+ .grid-cols-3 { grid-template-columns: repeat(3, 1fr); }
967
+ .grid-cols-4 { grid-template-columns: repeat(4, 1fr); }
968
+ .grid-cols-6 { grid-template-columns: repeat(6, 1fr); }
969
+
970
+ /* Auto-fit grids (responsive) */
971
+ .grid-auto-sm { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
972
+ .grid-auto-md { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
973
+ .grid-auto-lg { grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); }
974
+ .grid-auto-xl { grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); }
975
+
976
+ /* Gap utilities */
977
+ .gap-0 { gap: 0; }
978
+ .gap-xs { gap: var(--spacing-1); }
979
+ .gap-sm { gap: var(--spacing-2); }
980
+ .gap-md { gap: var(--spacing-4); }
981
+ .gap-lg { gap: var(--spacing-6); }
982
+ .gap-xl { gap: var(--spacing-8); }
983
+
984
+
985
+ /* Flexbox System */
986
+ .flex {
987
+ display: flex;
988
+ }
989
+
990
+ .flex-wrap {
991
+ flex-wrap: wrap;
992
+ }
993
+
994
+ .flex-col {
995
+ flex-direction: column;
996
+ }
997
+
998
+ .flex-row {
999
+ flex-direction: row;
1000
+ }
1001
+
1002
+ /* Flex alignment */
1003
+ .items-start { align-items: flex-start; }
1004
+ .items-center { align-items: center; }
1005
+ .items-end { align-items: flex-end; }
1006
+ .items-stretch { align-items: stretch; }
1007
+ .items-baseline { align-items: baseline; }
1008
+
1009
+ .justify-start { justify-content: flex-start; }
1010
+ .justify-center { justify-content: center; }
1011
+ .justify-end { justify-content: flex-end; }
1012
+ .justify-between { justify-content: space-between; }
1013
+ .justify-around { justify-content: space-around; }
1014
+ .justify-evenly { justify-content: space-evenly; }
1015
+
1016
+ /* Responsive helpers */
1017
+ @media (max-width: 767px) {
1018
+ .mobile-stack { flex-direction: column; }
1019
+ .mobile-stack > * { width: 100%; }
1020
+ }
1021
+
1022
+ /* ============================================================================
1023
+ Backdrop Utilities
1024
+ Reusable backdrop layer for modal components (dialogs, drawers, overlays)
1025
+ ============================================================================ */
1026
+
1027
+ /* Base backdrop class for modal overlays */
1028
+ .backdrop {
1029
+ position: fixed;
1030
+ inset: 0;
1031
+ background: var(--backdrop-bg);
1032
+ backdrop-filter: var(--backdrop-filter);
1033
+ opacity: 0;
1034
+ pointer-events: none;
1035
+ transition: opacity 0.2s ease;
1036
+ z-index: var(--z-modal, 1040);
1037
+
1038
+ &.active {
1039
+ opacity: var(--backdrop-opacity, 1);
1040
+ pointer-events: auto;
1041
+ }
1042
+
1043
+ /* Backdrop variants */
1044
+ &-light {
1045
+ --backdrop-bg: linear-gradient(135deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.2));
1046
+ --backdrop-brightness: 1.1;
1047
+ }
1048
+
1049
+ &-dark {
1050
+ --backdrop-bg: linear-gradient(135deg, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.5));
1051
+ --backdrop-brightness: 0.6;
1052
+ }
1053
+
1054
+ &-blur-sm {
1055
+ --backdrop-blur: 5px;
1056
+ }
1057
+
1058
+ &-blur-md {
1059
+ --backdrop-blur: 10px;
1060
+ }
1061
+
1062
+ &-blur-lg {
1063
+ --backdrop-blur: 20px;
1064
+ }
1065
+ }
1066
+
1067
+
1068
+ /* Optional utilities/features controlled by config options */
1069
+ /* - Body background mesh rule (applies one of the generated mesh vars) */
1070
+ /* - Liquid glass utility class */
1071
+ /* Optional background mesh applied from config */
1072
+ body {
1073
+ background: var(--background-mesh-04);
1074
+ background-attachment: fixed;
1075
+ }
1076
+ /* Liquid glass utility (opt-in via options.liquidGlassEffects) */
1077
+ .liquid-glass {
1078
+ border-radius: var(--radius-lg);
1079
+ /* Subtle translucent fill blended with surface */
1080
+ background: color-mix(in oklab, var(--color-surface-subtle) 45%, transparent);
1081
+
1082
+ background-image: linear-gradient(
1083
+ 135deg,
1084
+ rgba(255,255,255,0.35),
1085
+ rgba(255,255,255,0.12)
1086
+ );
1087
+ /* Frosted glass blur + saturation */
1088
+ -webkit-backdrop-filter: blur(12px) saturate(140%);
1089
+ backdrop-filter: blur(12px) saturate(140%);
1090
+ /* Soft inner highlight and outer depth */
1091
+ box-shadow:
1092
+ inset 0 1px 0 rgba(255,255,255,0.6),
1093
+ inset 0 -40px 80px rgba(255,255,255,0.12),
1094
+ 0 10px 30px rgba(0,0,0,0.10);
1095
+ /* Glossy border with slight light and dark edges */
1096
+ border: 1px solid color-mix(in oklab, var(--color-primary-500) 22%, transparent);
1097
+ outline: 1px solid color-mix(in oklab, #ffffff 18%, transparent);
1098
+ outline-offset: -1px;
1099
+ }
1100
+
1101
+ html[data-theme="dark"] .liquid-glass {
1102
+ background: color-mix(in oklab, var(--color-surface-inverse) 45%, transparent);
1103
+ background-image: linear-gradient(
1104
+ 135deg,
1105
+ color-mix(in oklab, var(--color-primary-300) 40%, transparent),
1106
+ color-mix(in oklab, var(--color-surface-overlay) 48%, transparent)
1107
+ );
1108
+ box-shadow:
1109
+ inset 0 1px 0 rgba(255,255,255,0.12),
1110
+ inset 0 -40px 80px rgba(0,0,0,0.55),
1111
+ 0 18px 38px rgba(0,0,0,0.65);
1112
+ border: 1px solid color-mix(in oklab, var(--color-primary-300) 26%, transparent);
1113
+ outline: 1px solid color-mix(in oklab, #ffffff 16%, transparent);
1114
+ }
1115
+
1116
+ /* Fallback when backdrop-filter isn't supported */
1117
+ @supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
1118
+ .liquid-glass {
1119
+ /* Strengthen fill a bit to compensate for lack of blur */
1120
+ background: color-mix(in oklab, var(--color-surface-subtle) 70%, rgba(255,255,255,0.4));
1121
+ box-shadow:
1122
+ inset 0 1px 0 rgba(255,255,255,0.6),
1123
+ 0 10px 24px rgba(0,0,0,0.08);
1124
+ }
1125
+
1126
+ html[data-theme="dark"] .liquid-glass {
1127
+ background: color-mix(in oklab, var(--color-surface-inverse) 70%, transparent);
1128
+ box-shadow:
1129
+ inset 0 1px 0 rgba(255,255,255,0.1),
1130
+ 0 18px 32px rgba(0,0,0,0.58);
1131
+ }
1132
+ }
1133
+
1134
+
1135
+ /* ============================================================================
1136
+ Border Gradient Utilities
1137
+ Card outlines with gradient borders and glow effects
1138
+ ============================================================================ */
1139
+
1140
+
1141
+ /* Gradient border utility - premium/promo card style */
1142
+ .border-gradient {
1143
+ border: var(--border-width-medium) solid transparent;
1144
+ background:
1145
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
1146
+ linear-gradient(var(--gradient-angle, 135deg),
1147
+ var(--color-primary-400),
1148
+ var(--color-accent-400)
1149
+ ) border-box;
1150
+ }
1151
+
1152
+ /* Gradient border variants - different color combinations */
1153
+ .border-gradient-primary {
1154
+ border: var(--border-width-medium) solid transparent;
1155
+ background:
1156
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
1157
+ linear-gradient(var(--gradient-angle, 135deg),
1158
+ var(--color-primary-300),
1159
+ var(--color-primary-600)
1160
+ ) border-box;
1161
+ }
1162
+
1163
+ .border-gradient-accent {
1164
+ border: var(--border-width-medium) solid transparent;
1165
+ background:
1166
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
1167
+ linear-gradient(var(--gradient-angle, 135deg),
1168
+ var(--color-accent-300),
1169
+ var(--color-accent-600)
1170
+ ) border-box;
1171
+ }
1172
+
1173
+ .border-gradient-secondary {
1174
+ border: var(--border-width-medium) solid transparent;
1175
+ background:
1176
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
1177
+ linear-gradient(var(--gradient-angle, 135deg),
1178
+ var(--color-secondary-300),
1179
+ var(--color-secondary-600)
1180
+ ) border-box;
1181
+ }
1182
+
1183
+ /* Gradient border with different strengths/thickness */
1184
+ .border-gradient-soft {
1185
+ border: 1px solid transparent;
1186
+ background:
1187
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
1188
+ linear-gradient(var(--gradient-angle, 135deg),
1189
+ var(--color-primary-400),
1190
+ var(--color-accent-400)
1191
+ ) border-box;
1192
+ }
1193
+
1194
+ .border-gradient-medium {
1195
+ border: 2px solid transparent;
1196
+ background:
1197
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
1198
+ linear-gradient(var(--gradient-angle, 135deg),
1199
+ var(--color-primary-400),
1200
+ var(--color-accent-400)
1201
+ ) border-box;
1202
+ }
1203
+
1204
+ .border-gradient-strong {
1205
+ border: 3px solid transparent;
1206
+ background:
1207
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
1208
+ linear-gradient(var(--gradient-angle, 135deg),
1209
+ var(--color-primary-400),
1210
+ var(--color-accent-400)
1211
+ ) border-box;
1212
+ }
1213
+
1214
+ /* Glow effect utility - for callouts and active states */
1215
+ .border-glow {
1216
+ box-shadow: 0 0 12px var(--color-primary-500);
1217
+ }
1218
+
1219
+ .border-glow-sm {
1220
+ box-shadow: 0 0 6px var(--color-primary-500);
1221
+ }
1222
+
1223
+ .border-glow-lg {
1224
+ box-shadow: 0 0 20px var(--color-primary-500);
1225
+ }
1226
+
1227
+ /* Combined gradient + glow for premium effects */
1228
+ .border-gradient-glow {
1229
+ border: var(--border-width-medium) solid transparent;
1230
+ background:
1231
+ linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
1232
+ linear-gradient(135deg,
1233
+ var(--color-primary-400),
1234
+ var(--color-accent-400)
1235
+ ) border-box;
1236
+ box-shadow: 0 0 12px var(--color-primary-500);
1237
+ }
1238
+
1239
+ /* Semantic glow variants */
1240
+ .border-glow-primary {
1241
+ box-shadow: 0 0 12px var(--color-primary-500);
1242
+ }
1243
+
1244
+ .border-glow-accent {
1245
+ box-shadow: 0 0 12px var(--color-accent-500);
1246
+ }
1247
+
1248
+ .border-glow-success {
1249
+ box-shadow: 0 0 12px var(--color-success-500);
1250
+ }
1251
+
1252
+ .border-glow-warning {
1253
+ box-shadow: 0 0 12px var(--color-warning-500);
1254
+ }
1255
+
1256
+ .border-glow-danger {
1257
+ box-shadow: 0 0 12px var(--color-danger-500);
1258
+ }
1259
+
1260
+
1261
+
1262
+ /* Surface utilities */
1263
+
1264
+ .surface {
1265
+ background-color: var(--color-surface-base);
1266
+ }
1267
+
1268
+ .surface-subtle {
1269
+ background-color: var(--color-surface-subtle);
1270
+ }
1271
+
1272
+ .surface-elevated {
1273
+ background-color: var(--color-surface-elevated);
1274
+ }
1275
+
1276
+ .surface-sunken {
1277
+ background-color: var(--color-surface-sunken);
1278
+ }
1279
+
1280
+ .surface-overlay {
1281
+ background-color: var(--color-surface-overlay);
1282
+ }
1283
+
1284
+ /* Translucent semantic variants */
1285
+ .surface-translucent {
1286
+ background-color: var(--color-surface-translucent-50);
1287
+ }
1288
+
1289
+ .surface-translucent-25 {
1290
+ background-color: var(--color-surface-translucent-25);
1291
+ }
1292
+
1293
+ .surface-translucent-50 {
1294
+ background-color: var(--color-surface-translucent-50);
1295
+ }
1296
+
1297
+ .surface-translucent-75 {
1298
+ background-color: var(--color-surface-translucent-75);
1299
+ }
1300
+
1301
+ /* Legacy utility retained for backwards compatibility (opinionated overlay) */
1302
+ .surface-overlay {
1303
+ padding: var(--spacing-4);
1304
+ background-color: var(--color-surface-overlay);
1305
+ box-shadow: var(--shadow-lg);
1306
+ border-radius: var(--radius-md);
1307
+ }
1308
+
1309
+
1310
+ /* Inverse surface (dark) using PDS tokens; text/icons inherit currentColor */
1311
+ .surface-inverse {
1312
+ background-color: var(--color-surface-inverse);
1313
+ /* Ensure foregrounds inside use the correct smart-surface tokens */
1314
+ color: var(--surface-inverse-text);
1315
+ --color-text-primary: var(--surface-inverse-text);
1316
+ --color-text-secondary: var(--surface-inverse-text-secondary);
1317
+ --color-text-muted: var(--surface-inverse-text-muted);
1318
+ /* Ensure code/pre and other muted surfaces have contrast on inverse */
1319
+ --color-surface-muted: rgba(255, 255, 255, 0.08);
1320
+ /* Optional: adjust borders/shadows if utilities/components read these */
1321
+ --color-border: var(--surface-inverse-border);
1322
+
1323
+ pds-icon {
1324
+ color: var(--surface-inverse-icon);
1325
+ }
1326
+ }
1327
+
1328
+ /* Shadow utilities */
1329
+ .shadow-sm {
1330
+ box-shadow: var(--shadow-sm);
1331
+ }
1332
+
1333
+ .shadow-base, .shadow {
1334
+ box-shadow: var(--shadow-base);
1335
+ }
1336
+
1337
+ .shadow-md {
1338
+ box-shadow: var(--shadow-md);
1339
+ }
1340
+
1341
+ .shadow-lg {
1342
+ box-shadow: var(--shadow-lg);
1343
+ }
1344
+
1345
+ .shadow-xl {
1346
+ box-shadow: var(--shadow-xl);
1347
+ }
1348
+
1349
+ .shadow-inner {
1350
+ box-shadow: var(--shadow-inner);
1351
+ }
1352
+
1353
+ .shadow-none {
1354
+ box-shadow: none;
1355
+ }
1356
+
1357
+ .text-muted {
1358
+ color: var(--color-text-muted);
1359
+ }
1360
+
1361
+
1362
+ /* Media Element Utilities */
1363
+
1364
+ /* Gallery images */
1365
+ .img-gallery {
1366
+ width: 100%;
1367
+ height: auto;
1368
+ aspect-ratio: 1;
1369
+ object-fit: cover;
1370
+ border-radius: var(--radius-sm);
1371
+ }
1372
+
1373
+ /* Responsive images with different radius sizes */
1374
+ .img-rounded-sm { border-radius: var(--radius-sm); }
1375
+ .img-rounded-md { border-radius: var(--radius-md); }
1376
+ .img-rounded-lg { border-radius: var(--radius-lg); }
1377
+ .img-rounded-xl { border-radius: var(--radius-xl); }
1378
+ .img-rounded-full { border-radius: var(--radius-full); }
1379
+
1380
+ /* Inline images */
1381
+ .img-inline {
1382
+ display: inline;
1383
+ vertical-align: middle;
1384
+ border-radius: var(--radius-xs);
1385
+ margin: 0 var(--spacing-1);
1386
+ max-width: 60px;
1387
+ height: auto;
1388
+ }
1389
+
1390
+ /* Video specific utilities */
1391
+ .video-responsive {
1392
+ width: 100%;
1393
+ max-width: 600px;
1394
+ height: auto;
1395
+ border-radius: var(--radius-md);
1396
+ }
1397
+
1398
+ /* Figure utilities */
1399
+ .figure-responsive {
1400
+ width: 100%;
1401
+ height: auto;
1402
+ }
1403
+
1404
+
1405
+
1406
+ /* Mobile-First Responsive Design */
1407
+
1408
+ /* Small devices (640px and up) */
1409
+ @media (min-width: 640px) {
1410
+ .sm\\:grid-cols-2 { grid-template-columns: repeat(2, 1fr); }
1411
+ .sm\\:flex-row { flex-direction: row; }
1412
+ .sm\\:text-sm { font-size: var(--font-size-sm); }
1413
+ .sm\\:p-6 { padding: var(--spacing-6); }
1414
+ .sm\\:gap-6 { gap: var(--spacing-6); }
1415
+ .sm\\:hidden { display: none; }
1416
+ .sm\\:block { display: block; }
1417
+ }
1418
+
1419
+ /* Medium devices (768px and up) */
1420
+ @media (min-width: 768px) {
1421
+ .md\\:grid-cols-3 { grid-template-columns: repeat(3, 1fr); }
1422
+ .md\\:text-lg { font-size: var(--font-size-lg); }
1423
+ .md\\:p-8 { padding: var(--spacing-8); }
1424
+ .md\\:gap-8 { gap: var(--spacing-8); }
1425
+ .md\\:flex-row { flex-direction: row; }
1426
+ .md\\:w-1\\/2 { width: 50%; }
1427
+ .md\\:w-1\\/3 { width: 33.333333%; }
1428
+ .md\\:hidden { display: none; }
1429
+ .md\\:block { display: block; }
1430
+ }
1431
+
1432
+ /* Large devices (1024px and up) */
1433
+ @media (min-width: 1024px) {
1434
+ .lg\\:grid-cols-4 { grid-template-columns: repeat(4, 1fr); }
1435
+ .lg\\:text-xl { font-size: var(--font-size-xl); }
1436
+ .lg\\:p-12 { padding: var(--spacing-12); }
1437
+ .lg\\:gap-12 { gap: var(--spacing-12); }
1438
+ .lg\\:w-1\\/4 { width: 25%; }
1439
+ .lg\\:hidden { display: none; }
1440
+ .lg\\:block { display: block; }
1441
+ }
1442
+
1443
+ /* Touch device optimizations */
1444
+ @media (hover: none) and (pointer: coarse) {
1445
+ /* Touch devices - larger touch targets for interactive elements */
1446
+ button, a, select, textarea,
1447
+ input:not([type="radio"]):not([type="checkbox"]) {
1448
+ min-height: 44px;
1449
+ min-width: 44px;
1450
+ }
1451
+
1452
+ /* Radio and checkbox inputs: keep reasonable size but ensure label tap area is large */
1453
+ input[type="radio"],
1454
+ input[type="checkbox"] {
1455
+ /* Keep native size - labels provide the touch target */
1456
+ min-height: unset;
1457
+ min-width: unset;
1458
+ }
1459
+
1460
+ /* Ensure labels with radio/checkbox have adequate touch targets */
1461
+ /* Exclude button-style fieldsets which already have proper sizing */
1462
+ label:has(input[type="radio"]):not(fieldset.buttons label),
1463
+ label:has(input[type="checkbox"]):not(fieldset.buttons label),
1464
+ fieldset[role="radiogroup"]:not(.buttons) label,
1465
+ fieldset[role="group"]:not(.buttons) label {
1466
+ min-height: 44px;
1467
+ display: inline-flex;
1468
+ align-items: center;
1469
+ padding: var(--spacing-2) 0;
1470
+ }
1471
+
1472
+ /* Disable hover effects
1473
+ on touch devices */
1474
+ .card {
1475
+ &:hover {
1476
+ box-shadow: var(--shadow-base);
1477
+ }
1478
+ }
1479
+
1480
+ a {
1481
+ &:hover {
1482
+ color: var(--color-primary-600);
1483
+ }
1484
+ }
1485
+ }
1486
+
1487
+ /* Reduced motion */
1488
+ @media (prefers-reduced-motion: reduce) {
1489
+ *, *::before, *::after {
1490
+ animation-duration: 0.01ms !important;
1491
+ animation-iteration-count: 1 !important;
1492
+ transition-duration: 0.01ms !important;
1493
+ scroll-behavior: auto !important;
1494
+ }
1495
+ }
1496
+
1497
+ /* High contrast mode */
1498
+ @media (prefers-contrast: high) {
1499
+ :root {
1500
+ --color-primary-600: #0000ff;
1501
+ --color-primary-700: #0000cc;
1502
+ }
1503
+
1504
+ button, input, textarea, select {
1505
+ border-width: 2px;
1506
+ }
1507
+ }
1508
+
1509
+ /* Print styles */
1510
+ @media print {
1511
+ *, *::before, *::after {
1512
+ background: transparent !important;
1513
+ color: black !important;
1514
+ box-shadow: none !important;
1515
+ }
1516
+
1517
+ a, a:visited {
1518
+ text-decoration: underline;
1519
+ }
1520
+
1521
+ button {
1522
+ display: none;
1523
+ }
1524
+
1525
+ .mobile-hidden, .desktop-hidden {
1526
+ display: block !important;
1527
+ }
1528
+ }
1529
+
1530
+
1531
+
1532
+ }
1533
+ `;