@keenmate/pure-admin-core 2.3.1 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +5 -5
  2. package/dist/css/main.css +187 -178
  3. package/package.json +1 -1
  4. package/snippets/buttons.html +375 -365
  5. package/src/scss/_base-css-variables.scss +8 -0
  6. package/src/scss/_core.scss +121 -121
  7. package/src/scss/core-components/_alerts.scss +227 -227
  8. package/src/scss/core-components/_badges.scss +16 -16
  9. package/src/scss/core-components/_base.scss +125 -125
  10. package/src/scss/core-components/_buttons.scss +31 -16
  11. package/src/scss/core-components/_callouts.scss +152 -152
  12. package/src/scss/core-components/_cards.scss +488 -488
  13. package/src/scss/core-components/_checkbox-lists.scss +289 -289
  14. package/src/scss/core-components/_code.scss +141 -141
  15. package/src/scss/core-components/_command-palette.scss +509 -509
  16. package/src/scss/core-components/_comparison.scss +172 -172
  17. package/src/scss/core-components/_data-display.scss +9 -9
  18. package/src/scss/core-components/_data-viz.scss +9 -9
  19. package/src/scss/core-components/_detail-panel.scss +1 -1
  20. package/src/scss/core-components/_file-selector.scss +780 -780
  21. package/src/scss/core-components/_filter-card.scss +58 -58
  22. package/src/scss/core-components/_forms.scss +16 -16
  23. package/src/scss/core-components/_grid.scss +293 -293
  24. package/src/scss/core-components/_layout.scss +15 -15
  25. package/src/scss/core-components/_lists.scss +211 -211
  26. package/src/scss/core-components/_loaders.scss +277 -277
  27. package/src/scss/core-components/_logic-tree.scss +280 -280
  28. package/src/scss/core-components/_modals.scss +203 -203
  29. package/src/scss/core-components/_notifications.scss +320 -320
  30. package/src/scss/core-components/_pagers.scss +141 -141
  31. package/src/scss/core-components/_popconfirm.scss +170 -170
  32. package/src/scss/core-components/_profile.scss +405 -405
  33. package/src/scss/core-components/_scrollbars.scss +40 -40
  34. package/src/scss/core-components/_settings-panel.scss +141 -141
  35. package/src/scss/core-components/_statistics.scss +200 -201
  36. package/src/scss/core-components/_tables.scss +900 -900
  37. package/src/scss/core-components/_tabs.scss +504 -504
  38. package/src/scss/core-components/_timeline.scss +589 -589
  39. package/src/scss/core-components/_toasts.scss +425 -425
  40. package/src/scss/core-components/_tooltips.scss +605 -605
  41. package/src/scss/core-components/_utilities.scss +1 -1
  42. package/src/scss/core-components/_web-components-theme.scss +21 -21
  43. package/src/scss/core-components/badges/_badge-base.scss +121 -121
  44. package/src/scss/core-components/badges/_badge-group.scss +25 -25
  45. package/src/scss/core-components/badges/_composite-badge-variants.scss +396 -396
  46. package/src/scss/core-components/badges/_composite-badge.scss +70 -70
  47. package/src/scss/core-components/badges/_index.scss +10 -10
  48. package/src/scss/core-components/badges/_labels.scss +155 -155
  49. package/src/scss/core-components/forms/_checkboxes-radios.scss +205 -205
  50. package/src/scss/core-components/forms/_form-inputs.scss +3 -3
  51. package/src/scss/core-components/forms/_form-layout.scss +66 -66
  52. package/src/scss/core-components/forms/_form-states.scss +115 -115
  53. package/src/scss/core-components/forms/_index.scss +12 -12
  54. package/src/scss/core-components/forms/_input-groups.scss +154 -154
  55. package/src/scss/core-components/forms/_input-wrapper.scss +89 -89
  56. package/src/scss/core-components/forms/_query-editor.scss +313 -313
  57. package/src/scss/core-components/layout/_index.scss +11 -11
  58. package/src/scss/core-components/layout/_layout-container.scss +168 -168
  59. package/src/scss/core-components/layout/_layout-responsive.scss +99 -99
  60. package/src/scss/core-components/layout/_navbar-elements.scss +250 -250
  61. package/src/scss/core-components/layout/_navbar.scss +83 -83
  62. package/src/scss/core-components/layout/_sidebar-states.scss +237 -237
  63. package/src/scss/core-components/layout/_sidebar.scss +234 -234
  64. package/src/scss/main.scss +7 -7
  65. package/src/scss/utilities.scss +740 -740
  66. package/src/scss/variables/_base.scss +228 -228
  67. package/src/scss/variables/_components.scss +748 -748
  68. package/src/scss/variables/_layout.scss +65 -65
  69. package/src/scss/variables/_typography.scss +37 -37
@@ -1,488 +1,488 @@
1
- /* ========================================
2
- Card Components
3
- Cards with headers, bodies, footers, variants, and card sections
4
- ======================================== */
5
- @use '../variables' as *;
6
-
7
- // Cards
8
- .pa-card {
9
- background: var(--pa-card-bg);
10
- border: $card-border-width solid var(--pa-border-color);
11
- border-radius: $card-border-radius;
12
- margin-bottom: $spacing-base;
13
- box-shadow: $shadow-sm;
14
- transition: box-shadow $transition-fast $easing-snappy;
15
- display: flex;
16
- flex-direction: column;
17
- overflow: hidden;
18
-
19
- &:hover {
20
- box-shadow: $shadow-lg;
21
- }
22
-
23
- &__header {
24
- padding: $card-header-padding-v $card-header-padding-h;
25
- min-height: $card-header-min-height;
26
- border-top-left-radius: $card-border-radius;
27
- border-top-right-radius: $card-border-radius;
28
- border-bottom: $border-width-base solid var(--pa-border-color);
29
- background: var(--pa-card-header-bg);
30
- display: flex;
31
- justify-content: space-between;
32
- align-items: center;
33
- gap: $spacing-base; // Gap between header elements (title, description, actions)
34
- min-width: 0; // Enable text truncation
35
-
36
- // Reset margins/paddings/borders for all native elements
37
- // (border-bottom reset prevents .pa-section h3 rule from bleeding in)
38
- h1,
39
- h2,
40
- h3,
41
- h4,
42
- h5,
43
- h6,
44
- p,
45
- ul,
46
- ol,
47
- dl,
48
- blockquote,
49
- pre,
50
- figure,
51
- fieldset {
52
- margin: 0;
53
- padding: 0;
54
- border-bottom: none;
55
- }
56
-
57
- // Specific heading styles
58
- h1,
59
- h2,
60
- h3,
61
- h4,
62
- h5,
63
- h6 {
64
- color: var(--pa-text-color-1);
65
- font-size: $font-size-base;
66
- }
67
-
68
- // Direct heading children - truncate when card is narrow
69
- > h1,
70
- > h2,
71
- > h3,
72
- > h4,
73
- > h5,
74
- > h6 {
75
- min-width: 0;
76
- overflow: hidden;
77
- text-overflow: ellipsis;
78
- white-space: nowrap;
79
- }
80
-
81
- // Description paragraphs - flexible middle, truncate with ellipsis
82
- > p {
83
- flex: 1;
84
- min-width: 0;
85
- overflow: hidden;
86
- text-overflow: ellipsis;
87
- white-space: nowrap;
88
- color: var(--pa-text-color-2);
89
- font-size: $font-size-sm;
90
- }
91
-
92
- // Actions container - fixed, doesn't shrink
93
- .pa-card__actions,
94
- .pa-btn-group {
95
- flex-shrink: 0;
96
- }
97
-
98
- // Buttons in card headers - negative margin to prevent header height growth
99
- .pa-btn {
100
- margin-top: -0.25rem;
101
- margin-bottom: -0.25rem;
102
- flex-shrink: 0;
103
- }
104
-
105
- // Underline modifier - accent border under heading inside card header
106
- &--underlined {
107
- h1, h2, h3, h4, h5, h6 {
108
- border-bottom: $border-width-medium solid var(--pa-accent);
109
- padding-bottom: $spacing-sm;
110
- }
111
-
112
- // Semantic color variants
113
- &.pa-card__header--underline-success h1,
114
- &.pa-card__header--underline-success h2,
115
- &.pa-card__header--underline-success h3,
116
- &.pa-card__header--underline-success h4,
117
- &.pa-card__header--underline-success h5,
118
- &.pa-card__header--underline-success h6 {
119
- border-bottom-color: var(--pa-success-bg);
120
- }
121
-
122
- &.pa-card__header--underline-warning h1,
123
- &.pa-card__header--underline-warning h2,
124
- &.pa-card__header--underline-warning h3,
125
- &.pa-card__header--underline-warning h4,
126
- &.pa-card__header--underline-warning h5,
127
- &.pa-card__header--underline-warning h6 {
128
- border-bottom-color: var(--pa-warning-bg);
129
- }
130
-
131
- &.pa-card__header--underline-danger h1,
132
- &.pa-card__header--underline-danger h2,
133
- &.pa-card__header--underline-danger h3,
134
- &.pa-card__header--underline-danger h4,
135
- &.pa-card__header--underline-danger h5,
136
- &.pa-card__header--underline-danger h6 {
137
- border-bottom-color: var(--pa-danger-bg);
138
- }
139
-
140
- &.pa-card__header--underline-info h1,
141
- &.pa-card__header--underline-info h2,
142
- &.pa-card__header--underline-info h3,
143
- &.pa-card__header--underline-info h4,
144
- &.pa-card__header--underline-info h5,
145
- &.pa-card__header--underline-info h6 {
146
- border-bottom-color: var(--pa-info-bg);
147
- }
148
-
149
- // Theme color slots (1-9)
150
- @for $i from 1 through 9 {
151
- &.pa-card__header--underline-color-#{$i} h1,
152
- &.pa-card__header--underline-color-#{$i} h2,
153
- &.pa-card__header--underline-color-#{$i} h3,
154
- &.pa-card__header--underline-color-#{$i} h4,
155
- &.pa-card__header--underline-color-#{$i} h5,
156
- &.pa-card__header--underline-color-#{$i} h6 {
157
- border-bottom-color: var(--pa-color-#{$i});
158
- }
159
- }
160
- }
161
-
162
- // Wrap modifier - allow heading and description to wrap instead of truncating
163
- &--wrap {
164
- flex-wrap: wrap;
165
-
166
- > h1, > h2, > h3, > h4, > h5, > h6 {
167
- white-space: normal;
168
- overflow: visible;
169
- text-overflow: clip;
170
- }
171
-
172
- > p {
173
- white-space: normal;
174
- flex-basis: 100%;
175
- order: 1;
176
- margin-top: $spacing-xs;
177
- }
178
- }
179
- }
180
-
181
- &__title {
182
- display: flex;
183
- align-items: center;
184
- gap: $spacing-sm;
185
- min-width: 0; // Enable text truncation
186
- flex: 1;
187
-
188
- &-icon {
189
- flex-shrink: 0;
190
- font-size: $font-size-base;
191
- line-height: 1;
192
- }
193
-
194
- &-text {
195
- overflow: hidden;
196
- text-overflow: ellipsis;
197
- white-space: nowrap;
198
- margin: 0;
199
- color: var(--pa-text-color-1);
200
- font-size: $font-size-base;
201
- font-weight: $font-weight-semibold;
202
- line-height: 1;
203
- }
204
- }
205
-
206
- &__body {
207
- padding: $card-body-padding-v $card-body-padding-h;
208
- flex: 1;
209
-
210
- // Remove top margin from first child to avoid double spacing with padding
211
- > :first-child {
212
- margin-top: 0;
213
- }
214
-
215
- &--no-padding {
216
- padding: 0;
217
- }
218
- }
219
-
220
- &__footer {
221
- padding: $card-footer-padding-v $card-footer-padding-h;
222
- border-top: $border-width-base solid var(--pa-border-color);
223
- border-bottom-left-radius: $border-radius-lg;
224
- border-bottom-right-radius: $border-radius-lg;
225
- background: var(--pa-card-footer-bg);
226
- display: flex;
227
- justify-content: space-between;
228
- align-items: center;
229
- }
230
-
231
- &__actions {
232
- display: flex;
233
- gap: $spacing-sm;
234
- align-items: center;
235
- }
236
-
237
- &__meta {
238
- color: var(--pa-text-color-2);
239
- font-size: $font-size-sm;
240
- }
241
-
242
- // Card variants
243
- &--primary {
244
- border-color: var(--pa-accent);
245
-
246
- .pa-card__header {
247
- background-color: var(--pa-accent);
248
- color: var(--pa-btn-primary-text);
249
-
250
- h1,
251
- h2,
252
- h3,
253
- h4,
254
- h5,
255
- h6 {
256
- color: var(--pa-btn-primary-text);
257
- }
258
- }
259
- }
260
-
261
- &--success {
262
- border-color: var(--pa-success-bg);
263
-
264
- .pa-card__header {
265
- background-color: var(--pa-success-bg);
266
- color: var(--pa-btn-success-text);
267
-
268
- h1,
269
- h2,
270
- h3,
271
- h4,
272
- h5,
273
- h6 {
274
- color: var(--pa-btn-success-text);
275
- }
276
- }
277
- }
278
-
279
- &--warning {
280
- border-color: var(--pa-warning-bg);
281
-
282
- .pa-card__header {
283
- background-color: var(--pa-warning-bg);
284
- color: var(--pa-btn-warning-text);
285
-
286
- h1,
287
- h2,
288
- h3,
289
- h4,
290
- h5,
291
- h6 {
292
- color: var(--pa-btn-warning-text);
293
- }
294
- }
295
- }
296
-
297
- &--danger {
298
- border-color: var(--pa-danger-bg);
299
-
300
- .pa-card__header {
301
- background-color: var(--pa-danger-bg);
302
- color: var(--pa-btn-danger-text);
303
-
304
- h1,
305
- h2,
306
- h3,
307
- h4,
308
- h5,
309
- h6 {
310
- color: var(--pa-btn-danger-text);
311
- }
312
- }
313
- }
314
-
315
- &--stat {
316
- .pa-card__body {
317
- padding: $card-stat-padding-v $card-stat-padding-h;
318
- }
319
- }
320
-
321
- // Ghost card - invisible container, same spacing/sizing behavior
322
- // Uses !important to beat dark-mode scoped overrides like
323
- // `.pa-mode-dark .pa-card { box-shadow: ... }` which have (0,2,0) specificity
324
- &--ghost {
325
- background: transparent !important;
326
- border: none !important;
327
- box-shadow: none !important;
328
-
329
- &:hover {
330
- box-shadow: none !important;
331
- }
332
-
333
- .pa-card__header {
334
- background: transparent !important;
335
- border-bottom: none !important;
336
- }
337
-
338
- .pa-card__footer {
339
- background: transparent !important;
340
- border-top: none !important;
341
- }
342
- }
343
-
344
- // Live-data state — persistent tinted background reflecting latest change
345
- // JS swaps the class on each data update; color stays until next update
346
- &--live-up {
347
- background-color: rgba($success-bg, 0.10);
348
- transition: background-color 0.3s ease;
349
- }
350
-
351
- &--live-down {
352
- background-color: rgba($danger-bg, 0.10);
353
- transition: background-color 0.3s ease;
354
- }
355
-
356
- &--live-neutral {
357
- background-color: $card-bg;
358
- transition: background-color 0.3s ease;
359
- }
360
-
361
- // Theme color variants (color-1 through color-9)
362
- // These use theme-customizable colors from --pa-color-* CSS variables
363
- @for $i from 1 through 9 {
364
- &--color-#{$i} {
365
- border-color: var(--pa-color-#{$i});
366
-
367
- .pa-card__header {
368
- background-color: var(--pa-color-#{$i});
369
- color: var(--pa-color-#{$i}-text);
370
-
371
- h1,
372
- h2,
373
- h3,
374
- h4,
375
- h5,
376
- h6 {
377
- color: var(--pa-color-#{$i}-text);
378
- }
379
- }
380
- }
381
- }
382
-
383
- // Card tabs
384
- &__tabs {
385
- display: flex;
386
- border-bottom: $border-width-base solid var(--pa-border-color);
387
- background: var(--pa-card-tabs-bg);
388
- }
389
-
390
- &__tab {
391
- padding: $card-footer-padding-v $card-footer-padding-h;
392
- border: none;
393
- background: none;
394
- color: var(--pa-text-color-2);
395
- cursor: pointer;
396
- transition: all $transition-fast $easing-snappy;
397
- border-bottom: $border-width-medium solid transparent;
398
-
399
- &:hover {
400
- color: var(--pa-text-color-1);
401
- background-color: rgba($accent-color, $card-tab-hover-opacity);
402
- }
403
-
404
- &--active {
405
- color: var(--pa-accent);
406
- border-bottom-color: var(--pa-accent);
407
- }
408
- }
409
-
410
- &__tab-content {
411
- display: none;
412
-
413
- &--active {
414
- display: block;
415
- }
416
- }
417
-
418
- // Inline tabs in header (for side-by-side card alignment)
419
- &__tabs--inline {
420
- display: flex;
421
- gap: $spacing-xs;
422
- margin: -$card-header-padding-v 0; // Negative margin to fill header height
423
- border-bottom: none;
424
- background: none;
425
-
426
- .pa-card__tab {
427
- padding: $card-tab-inline-padding-v $card-tab-inline-padding-h;
428
- border: none;
429
- border-radius: $border-radius;
430
- font-size: $font-size-sm;
431
- background: transparent;
432
- color: var(--pa-text-color-2);
433
- cursor: pointer;
434
- transition: all $transition-fast $easing-snappy;
435
-
436
- &:hover {
437
- background-color: rgba($accent-color, $card-tab-hover-opacity);
438
- color: var(--pa-text-color-1);
439
- }
440
-
441
- &--active {
442
- background: var(--pa-accent);
443
- color: var(--pa-btn-primary-text);
444
- }
445
- }
446
- }
447
- }
448
-
449
- // Clickable cards (anchor-wrapped)
450
- a.pa-card {
451
- text-decoration: none;
452
- display: block;
453
- color: inherit;
454
-
455
- &:hover,
456
- &:visited {
457
- color: inherit;
458
- }
459
-
460
- // Reset heading colors inside clickable cards
461
- h1, h2, h3, h4, h5, h6 {
462
- color: var(--pa-text-color-1);
463
- }
464
-
465
- p {
466
- color: var(--pa-text-color-2);
467
- }
468
- }
469
-
470
- // Card sections
471
- .pa-section {
472
- margin-bottom: $section-margin-v;
473
-
474
- > h3 {
475
- color: var(--pa-text-color-1);
476
- margin-bottom: $spacing-base;
477
- border-bottom: $border-width-medium solid var(--pa-accent);
478
- padding-bottom: $spacing-sm;
479
- }
480
- }
481
-
482
- // Section title (standalone)
483
- .pa-section-title {
484
- color: var(--pa-text-color-1);
485
- margin-bottom: $spacing-base;
486
- border-bottom: $border-width-medium solid var(--pa-accent);
487
- padding-bottom: $spacing-sm;
488
- }
1
+ /* ========================================
2
+ Card Components
3
+ Cards with headers, bodies, footers, variants, and card sections
4
+ ======================================== */
5
+ @use '../variables' as *;
6
+
7
+ // Cards
8
+ .pa-card {
9
+ background: var(--pa-card-bg);
10
+ border: $card-border-width solid var(--pa-border-color);
11
+ border-radius: var(--pa-border-radius-lg);
12
+ margin-bottom: $spacing-base;
13
+ box-shadow: $shadow-sm;
14
+ transition: box-shadow $transition-fast $easing-snappy;
15
+ display: flex;
16
+ flex-direction: column;
17
+ overflow: hidden;
18
+
19
+ &:hover {
20
+ box-shadow: $shadow-lg;
21
+ }
22
+
23
+ &__header {
24
+ padding: $card-header-padding-v $card-header-padding-h;
25
+ min-height: $card-header-min-height;
26
+ border-top-left-radius: $card-border-radius;
27
+ border-top-right-radius: $card-border-radius;
28
+ border-bottom: $border-width-base solid var(--pa-border-color);
29
+ background: var(--pa-card-header-bg);
30
+ display: flex;
31
+ justify-content: space-between;
32
+ align-items: center;
33
+ gap: $spacing-base; // Gap between header elements (title, description, actions)
34
+ min-width: 0; // Enable text truncation
35
+
36
+ // Reset margins/paddings/borders for all native elements
37
+ // (border-bottom reset prevents .pa-section h3 rule from bleeding in)
38
+ h1,
39
+ h2,
40
+ h3,
41
+ h4,
42
+ h5,
43
+ h6,
44
+ p,
45
+ ul,
46
+ ol,
47
+ dl,
48
+ blockquote,
49
+ pre,
50
+ figure,
51
+ fieldset {
52
+ margin: 0;
53
+ padding: 0;
54
+ border-bottom: none;
55
+ }
56
+
57
+ // Specific heading styles
58
+ h1,
59
+ h2,
60
+ h3,
61
+ h4,
62
+ h5,
63
+ h6 {
64
+ color: var(--pa-text-color-1);
65
+ font-size: $font-size-base;
66
+ }
67
+
68
+ // Direct heading children - truncate when card is narrow
69
+ > h1,
70
+ > h2,
71
+ > h3,
72
+ > h4,
73
+ > h5,
74
+ > h6 {
75
+ min-width: 0;
76
+ overflow: hidden;
77
+ text-overflow: ellipsis;
78
+ white-space: nowrap;
79
+ }
80
+
81
+ // Description paragraphs - flexible middle, truncate with ellipsis
82
+ > p {
83
+ flex: 1;
84
+ min-width: 0;
85
+ overflow: hidden;
86
+ text-overflow: ellipsis;
87
+ white-space: nowrap;
88
+ color: var(--pa-text-color-2);
89
+ font-size: $font-size-sm;
90
+ }
91
+
92
+ // Actions container - fixed, doesn't shrink
93
+ .pa-card__actions,
94
+ .pa-btn-group {
95
+ flex-shrink: 0;
96
+ }
97
+
98
+ // Buttons in card headers - negative margin to prevent header height growth
99
+ .pa-btn {
100
+ margin-top: -0.25rem;
101
+ margin-bottom: -0.25rem;
102
+ flex-shrink: 0;
103
+ }
104
+
105
+ // Underline modifier - accent border under heading inside card header
106
+ &--underlined {
107
+ h1, h2, h3, h4, h5, h6 {
108
+ border-bottom: $border-width-medium solid var(--pa-accent);
109
+ padding-bottom: $spacing-sm;
110
+ }
111
+
112
+ // Semantic color variants
113
+ &.pa-card__header--underline-success h1,
114
+ &.pa-card__header--underline-success h2,
115
+ &.pa-card__header--underline-success h3,
116
+ &.pa-card__header--underline-success h4,
117
+ &.pa-card__header--underline-success h5,
118
+ &.pa-card__header--underline-success h6 {
119
+ border-bottom-color: var(--pa-success-bg);
120
+ }
121
+
122
+ &.pa-card__header--underline-warning h1,
123
+ &.pa-card__header--underline-warning h2,
124
+ &.pa-card__header--underline-warning h3,
125
+ &.pa-card__header--underline-warning h4,
126
+ &.pa-card__header--underline-warning h5,
127
+ &.pa-card__header--underline-warning h6 {
128
+ border-bottom-color: var(--pa-warning-bg);
129
+ }
130
+
131
+ &.pa-card__header--underline-danger h1,
132
+ &.pa-card__header--underline-danger h2,
133
+ &.pa-card__header--underline-danger h3,
134
+ &.pa-card__header--underline-danger h4,
135
+ &.pa-card__header--underline-danger h5,
136
+ &.pa-card__header--underline-danger h6 {
137
+ border-bottom-color: var(--pa-danger-bg);
138
+ }
139
+
140
+ &.pa-card__header--underline-info h1,
141
+ &.pa-card__header--underline-info h2,
142
+ &.pa-card__header--underline-info h3,
143
+ &.pa-card__header--underline-info h4,
144
+ &.pa-card__header--underline-info h5,
145
+ &.pa-card__header--underline-info h6 {
146
+ border-bottom-color: var(--pa-info-bg);
147
+ }
148
+
149
+ // Theme color slots (1-9)
150
+ @for $i from 1 through 9 {
151
+ &.pa-card__header--underline-color-#{$i} h1,
152
+ &.pa-card__header--underline-color-#{$i} h2,
153
+ &.pa-card__header--underline-color-#{$i} h3,
154
+ &.pa-card__header--underline-color-#{$i} h4,
155
+ &.pa-card__header--underline-color-#{$i} h5,
156
+ &.pa-card__header--underline-color-#{$i} h6 {
157
+ border-bottom-color: var(--pa-color-#{$i});
158
+ }
159
+ }
160
+ }
161
+
162
+ // Wrap modifier - allow heading and description to wrap instead of truncating
163
+ &--wrap {
164
+ flex-wrap: wrap;
165
+
166
+ > h1, > h2, > h3, > h4, > h5, > h6 {
167
+ white-space: normal;
168
+ overflow: visible;
169
+ text-overflow: clip;
170
+ }
171
+
172
+ > p {
173
+ white-space: normal;
174
+ flex-basis: 100%;
175
+ order: 1;
176
+ margin-top: $spacing-xs;
177
+ }
178
+ }
179
+ }
180
+
181
+ &__title {
182
+ display: flex;
183
+ align-items: center;
184
+ gap: $spacing-sm;
185
+ min-width: 0; // Enable text truncation
186
+ flex: 1;
187
+
188
+ &-icon {
189
+ flex-shrink: 0;
190
+ font-size: $font-size-base;
191
+ line-height: 1;
192
+ }
193
+
194
+ &-text {
195
+ overflow: hidden;
196
+ text-overflow: ellipsis;
197
+ white-space: nowrap;
198
+ margin: 0;
199
+ color: var(--pa-text-color-1);
200
+ font-size: $font-size-base;
201
+ font-weight: $font-weight-semibold;
202
+ line-height: 1;
203
+ }
204
+ }
205
+
206
+ &__body {
207
+ padding: $card-body-padding-v $card-body-padding-h;
208
+ flex: 1;
209
+
210
+ // Remove top margin from first child to avoid double spacing with padding
211
+ > :first-child {
212
+ margin-top: 0;
213
+ }
214
+
215
+ &--no-padding {
216
+ padding: 0;
217
+ }
218
+ }
219
+
220
+ &__footer {
221
+ padding: $card-footer-padding-v $card-footer-padding-h;
222
+ border-top: $border-width-base solid var(--pa-border-color);
223
+ border-bottom-left-radius: var(--pa-border-radius-lg);
224
+ border-bottom-right-radius: var(--pa-border-radius-lg);
225
+ background: var(--pa-card-footer-bg);
226
+ display: flex;
227
+ justify-content: space-between;
228
+ align-items: center;
229
+ }
230
+
231
+ &__actions {
232
+ display: flex;
233
+ gap: $spacing-sm;
234
+ align-items: center;
235
+ }
236
+
237
+ &__meta {
238
+ color: var(--pa-text-color-2);
239
+ font-size: $font-size-sm;
240
+ }
241
+
242
+ // Card variants
243
+ &--primary {
244
+ border-color: var(--pa-accent);
245
+
246
+ .pa-card__header {
247
+ background-color: var(--pa-accent);
248
+ color: var(--pa-btn-primary-text);
249
+
250
+ h1,
251
+ h2,
252
+ h3,
253
+ h4,
254
+ h5,
255
+ h6 {
256
+ color: var(--pa-btn-primary-text);
257
+ }
258
+ }
259
+ }
260
+
261
+ &--success {
262
+ border-color: var(--pa-success-bg);
263
+
264
+ .pa-card__header {
265
+ background-color: var(--pa-success-bg);
266
+ color: var(--pa-btn-success-text);
267
+
268
+ h1,
269
+ h2,
270
+ h3,
271
+ h4,
272
+ h5,
273
+ h6 {
274
+ color: var(--pa-btn-success-text);
275
+ }
276
+ }
277
+ }
278
+
279
+ &--warning {
280
+ border-color: var(--pa-warning-bg);
281
+
282
+ .pa-card__header {
283
+ background-color: var(--pa-warning-bg);
284
+ color: var(--pa-btn-warning-text);
285
+
286
+ h1,
287
+ h2,
288
+ h3,
289
+ h4,
290
+ h5,
291
+ h6 {
292
+ color: var(--pa-btn-warning-text);
293
+ }
294
+ }
295
+ }
296
+
297
+ &--danger {
298
+ border-color: var(--pa-danger-bg);
299
+
300
+ .pa-card__header {
301
+ background-color: var(--pa-danger-bg);
302
+ color: var(--pa-btn-danger-text);
303
+
304
+ h1,
305
+ h2,
306
+ h3,
307
+ h4,
308
+ h5,
309
+ h6 {
310
+ color: var(--pa-btn-danger-text);
311
+ }
312
+ }
313
+ }
314
+
315
+ &--stat {
316
+ .pa-card__body {
317
+ padding: $card-stat-padding-v $card-stat-padding-h;
318
+ }
319
+ }
320
+
321
+ // Ghost card - invisible container, same spacing/sizing behavior
322
+ // Uses !important to beat dark-mode scoped overrides like
323
+ // `.pa-mode-dark .pa-card { box-shadow: ... }` which have (0,2,0) specificity
324
+ &--ghost {
325
+ background: transparent !important;
326
+ border: none !important;
327
+ box-shadow: none !important;
328
+
329
+ &:hover {
330
+ box-shadow: none !important;
331
+ }
332
+
333
+ .pa-card__header {
334
+ background: transparent !important;
335
+ border-bottom: none !important;
336
+ }
337
+
338
+ .pa-card__footer {
339
+ background: transparent !important;
340
+ border-top: none !important;
341
+ }
342
+ }
343
+
344
+ // Live-data state — persistent tinted background reflecting latest change
345
+ // JS swaps the class on each data update; color stays until next update
346
+ &--live-up {
347
+ background-color: rgba($success-bg, 0.10);
348
+ transition: background-color 0.3s ease;
349
+ }
350
+
351
+ &--live-down {
352
+ background-color: rgba($danger-bg, 0.10);
353
+ transition: background-color 0.3s ease;
354
+ }
355
+
356
+ &--live-neutral {
357
+ background-color: $card-bg;
358
+ transition: background-color 0.3s ease;
359
+ }
360
+
361
+ // Theme color variants (color-1 through color-9)
362
+ // These use theme-customizable colors from --pa-color-* CSS variables
363
+ @for $i from 1 through 9 {
364
+ &--color-#{$i} {
365
+ border-color: var(--pa-color-#{$i});
366
+
367
+ .pa-card__header {
368
+ background-color: var(--pa-color-#{$i});
369
+ color: var(--pa-color-#{$i}-text);
370
+
371
+ h1,
372
+ h2,
373
+ h3,
374
+ h4,
375
+ h5,
376
+ h6 {
377
+ color: var(--pa-color-#{$i}-text);
378
+ }
379
+ }
380
+ }
381
+ }
382
+
383
+ // Card tabs
384
+ &__tabs {
385
+ display: flex;
386
+ border-bottom: $border-width-base solid var(--pa-border-color);
387
+ background: var(--pa-card-tabs-bg);
388
+ }
389
+
390
+ &__tab {
391
+ padding: $card-footer-padding-v $card-footer-padding-h;
392
+ border: none;
393
+ background: none;
394
+ color: var(--pa-text-color-2);
395
+ cursor: pointer;
396
+ transition: all $transition-fast $easing-snappy;
397
+ border-bottom: $border-width-medium solid transparent;
398
+
399
+ &:hover {
400
+ color: var(--pa-text-color-1);
401
+ background-color: rgba($accent-color, $card-tab-hover-opacity);
402
+ }
403
+
404
+ &--active {
405
+ color: var(--pa-accent);
406
+ border-bottom-color: var(--pa-accent);
407
+ }
408
+ }
409
+
410
+ &__tab-content {
411
+ display: none;
412
+
413
+ &--active {
414
+ display: block;
415
+ }
416
+ }
417
+
418
+ // Inline tabs in header (for side-by-side card alignment)
419
+ &__tabs--inline {
420
+ display: flex;
421
+ gap: $spacing-xs;
422
+ margin: -$card-header-padding-v 0; // Negative margin to fill header height
423
+ border-bottom: none;
424
+ background: none;
425
+
426
+ .pa-card__tab {
427
+ padding: $card-tab-inline-padding-v $card-tab-inline-padding-h;
428
+ border: none;
429
+ border-radius: var(--pa-border-radius);
430
+ font-size: $font-size-sm;
431
+ background: transparent;
432
+ color: var(--pa-text-color-2);
433
+ cursor: pointer;
434
+ transition: all $transition-fast $easing-snappy;
435
+
436
+ &:hover {
437
+ background-color: rgba($accent-color, $card-tab-hover-opacity);
438
+ color: var(--pa-text-color-1);
439
+ }
440
+
441
+ &--active {
442
+ background: var(--pa-accent);
443
+ color: var(--pa-btn-primary-text);
444
+ }
445
+ }
446
+ }
447
+ }
448
+
449
+ // Clickable cards (anchor-wrapped)
450
+ a.pa-card {
451
+ text-decoration: none;
452
+ display: block;
453
+ color: inherit;
454
+
455
+ &:hover,
456
+ &:visited {
457
+ color: inherit;
458
+ }
459
+
460
+ // Reset heading colors inside clickable cards
461
+ h1, h2, h3, h4, h5, h6 {
462
+ color: var(--pa-text-color-1);
463
+ }
464
+
465
+ p {
466
+ color: var(--pa-text-color-2);
467
+ }
468
+ }
469
+
470
+ // Card sections
471
+ .pa-section {
472
+ margin-bottom: $section-margin-v;
473
+
474
+ > h3 {
475
+ color: var(--pa-text-color-1);
476
+ margin-bottom: $spacing-base;
477
+ border-bottom: $border-width-medium solid var(--pa-accent);
478
+ padding-bottom: $spacing-sm;
479
+ }
480
+ }
481
+
482
+ // Section title (standalone)
483
+ .pa-section-title {
484
+ color: var(--pa-text-color-1);
485
+ margin-bottom: $spacing-base;
486
+ border-bottom: $border-width-medium solid var(--pa-accent);
487
+ padding-bottom: $spacing-sm;
488
+ }