@pitchfork-ui/react 0.2.0 → 0.6.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 (69) hide show
  1. package/dist/components/Accordion/Accordion.css +85 -0
  2. package/dist/components/Accordion/Accordion2.js +96 -0
  3. package/dist/components/Alert/Alert.css +29 -1
  4. package/dist/components/Alert/Alert2.js +4 -2
  5. package/dist/components/Avatar/Avatar.css +1 -1
  6. package/dist/components/BadgeGroup/BadgeGroup.css +4 -4
  7. package/dist/components/Button/Button.css +4 -4
  8. package/dist/components/ButtonGroup/ButtonGroup.css +2 -2
  9. package/dist/components/Carousel/Carousel.css +4 -2
  10. package/dist/components/Carousel/Carousel2.js +89 -76
  11. package/dist/components/CodeSnippet/CodeSnippet.css +2 -2
  12. package/dist/components/ContentDivider/ContentDivider.css +2 -2
  13. package/dist/components/DatePicker/DatePicker.css +1 -1
  14. package/dist/components/DatePicker/DatePicker2.js +3 -3
  15. package/dist/components/Dropdown/Dropdown.css +19 -2
  16. package/dist/components/Dropdown/Dropdown2.js +2 -3
  17. package/dist/components/GaugeChart/GaugeChart.css +18 -1
  18. package/dist/components/GaugeChart/GaugeChart2.js +5 -4
  19. package/dist/components/Heatmap/Heatmap.css +100 -0
  20. package/dist/components/Heatmap/Heatmap2.js +160 -0
  21. package/dist/components/InlineCTA/InlineCTA.css +58 -0
  22. package/dist/components/InlineCTA/InlineCTA2.js +14 -2
  23. package/dist/components/Modal/Modal.css +62 -0
  24. package/dist/components/Modal/Modal2.js +8 -6
  25. package/dist/components/MultiSelect/MultiSelect.css +19 -2
  26. package/dist/components/MultiSelect/MultiSelect2.js +3 -4
  27. package/dist/components/Notification/Notification.css +59 -4
  28. package/dist/components/Notification/Notification2.js +4 -2
  29. package/dist/components/PieChart/PieChart.css +34 -0
  30. package/dist/components/PieChart/PieChart2.js +1 -1
  31. package/dist/components/ProgressIndicators/ProgressIndicators.css +20 -2
  32. package/dist/components/ProgressIndicators/ProgressIndicators2.js +4 -1
  33. package/dist/components/ProgressSteps/ProgressSteps.css +20 -3
  34. package/dist/components/RadarChart/RadarChart.css +22 -0
  35. package/dist/components/RadarChart/RadarChart2.js +19 -13
  36. package/dist/components/RichTextEditor/RichTextEditor.css +1 -1
  37. package/dist/components/Select/Select.css +21 -2
  38. package/dist/components/Select/Select2.js +3 -4
  39. package/dist/components/SidebarNavigation/SidebarNavigation.css +1 -1
  40. package/dist/components/SlideoutMenu/SlideoutMenu.css +2 -2
  41. package/dist/components/Sparkline/Sparkline.css +48 -0
  42. package/dist/components/Sparkline/Sparkline2.js +3 -2
  43. package/dist/components/Table/Table.css +4 -4
  44. package/dist/components/Tabs/Tabs.css +31 -5
  45. package/dist/components/Tabs/Tabs2.js +51 -4
  46. package/dist/components/Tag/Tag.css +1 -1
  47. package/dist/components/Tooltip/Tooltip.css +35 -0
  48. package/dist/components/Tooltip/Tooltip2.js +4 -4
  49. package/dist/components/TreeView/TreeView.css +2 -2
  50. package/dist/hooks/useExitAnimation.js +25 -0
  51. package/dist/hooks/usePresence.js +31 -0
  52. package/dist/index.cjs +834 -454
  53. package/dist/index.js +12 -8
  54. package/dist/src/components/Accordion/Accordion.d.ts +20 -0
  55. package/dist/src/components/Accordion/Accordion.test.d.ts +1 -0
  56. package/dist/src/components/Accordion/index.d.ts +1 -0
  57. package/dist/src/components/Heatmap/Heatmap.d.ts +28 -0
  58. package/dist/src/components/Heatmap/Heatmap.test.d.ts +1 -0
  59. package/dist/src/components/Heatmap/index.d.ts +1 -0
  60. package/dist/src/components/InlineCTA/InlineCTA.d.ts +2 -0
  61. package/dist/src/components/Sparkline/Sparkline.d.ts +2 -0
  62. package/dist/src/hooks/index.d.ts +2 -0
  63. package/dist/src/hooks/useExitAnimation.d.ts +18 -0
  64. package/dist/src/hooks/usePresence.d.ts +13 -0
  65. package/dist/src/index.d.ts +2 -0
  66. package/dist/styles/theme.css +47 -13
  67. package/dist/styles.css +758 -64
  68. package/package.json +1 -1
  69. package/theme.starter.css +4 -3
package/dist/styles.css CHANGED
@@ -15,16 +15,16 @@
15
15
  --color-gray-700: #334155;
16
16
  --color-gray-800: #1e293b;
17
17
  --color-gray-900: #0f172a;
18
- --color-brand-50: #eff6ff;
19
- --color-brand-100: #dbeafe;
20
- --color-brand-200: #bfdbfe;
21
- --color-brand-300: #93c5fd;
22
- --color-brand-400: #60a5fa;
23
- --color-brand-500: #3b82f6;
24
- --color-brand-600: #2563eb;
25
- --color-brand-700: #1d4ed8;
26
- --color-brand-800: #1e40af;
27
- --color-brand-900: #1e3a8a;
18
+ --color-brand-50: #eef2ff;
19
+ --color-brand-100: #e0e7ff;
20
+ --color-brand-200: #c7d2fe;
21
+ --color-brand-300: #a5b4fc;
22
+ --color-brand-400: #818cf8;
23
+ --color-brand-500: #6366f1;
24
+ --color-brand-600: #4f46e5;
25
+ --color-brand-700: #4338ca;
26
+ --color-brand-800: #3730a3;
27
+ --color-brand-900: #312e81;
28
28
  --color-success-50: #ecfdf3;
29
29
  --color-success-100: #d1fadf;
30
30
  --color-success-200: #a6f4c5;
@@ -55,6 +55,12 @@
55
55
  --color-danger-700: #b42318;
56
56
  --color-danger-800: #912018;
57
57
  --color-danger-900: #7a271a;
58
+ --duration-fast: 120ms;
59
+ --duration-moderate: 180ms;
60
+ --duration-slow: 280ms;
61
+ --easing-standard: cubic-bezier(0.4, 0, 0.2, 1);
62
+ --easing-decelerate: cubic-bezier(0, 0, 0.2, 1);
63
+ --easing-accelerate: cubic-bezier(0.4, 0, 1, 1);
58
64
  --shadow-sm: 0 1px 2px rgb(15 23 42 / 0.08);
59
65
  --shadow-md: 0 8px 24px rgb(15 23 42 / 0.12);
60
66
  --shadow-lg: 0 18px 48px rgb(15 23 42 / 0.16);
@@ -85,7 +91,7 @@
85
91
  --size-icon-sm: 1rem;
86
92
  --size-icon-md: 1.25rem;
87
93
  --size-icon-lg: 1.5rem;
88
- --font-family-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
94
+ --font-family-sans: Geist, Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
89
95
  --font-size-2xs: 0.6875rem;
90
96
  --font-size-xs: 0.75rem;
91
97
  --font-size-sm: 0.875rem;
@@ -148,8 +154,13 @@
148
154
  --pf-focus-ring: 0 0 0 var(--pf-focus-ring-width)
149
155
  color-mix(in srgb, var(--pf-focus-ring-color) 35%, transparent);
150
156
  --pf-focus-outline: var(--pf-focus-ring-width) solid var(--pf-focus-ring-color);
151
- --pf-transition-fast: 120ms ease;
152
- --pf-transition-medium: 180ms ease;
157
+ /* Motion — durations and easings come from Style Dictionary (--duration-*, --easing-*) */
158
+ --pf-transition-fast: var(--duration-fast) var(--easing-standard);
159
+ --pf-transition-medium: var(--duration-moderate) var(--easing-standard);
160
+ --pf-transition-slow: var(--duration-slow) var(--easing-standard);
161
+ /* Directional easings for enter/exit animations */
162
+ --pf-transition-enter: var(--duration-moderate) var(--easing-decelerate);
163
+ --pf-transition-exit: var(--duration-fast) var(--easing-accelerate);
153
164
 
154
165
  /* Control aliases */
155
166
  --pf-control-height-sm: var(--size-control-sm, 36px);
@@ -361,6 +372,19 @@
361
372
  --pf-utility-btn-danger-text: var(--color-semantic-status-danger-foreground);
362
373
  --pf-utility-btn-danger-bg-hover: var(--color-danger-100);
363
374
 
375
+ /* Accordion aliases */
376
+ --pf-accordion-border: var(--color-semantic-border-default);
377
+ --pf-accordion-trigger-text: var(--color-semantic-text-default);
378
+ --pf-accordion-trigger-bg-hover: var(--color-semantic-background-subtle);
379
+ --pf-accordion-icon: var(--color-semantic-text-muted);
380
+ --pf-accordion-content-text: var(--color-semantic-text-muted);
381
+
382
+ /* Heatmap aliases */
383
+ --pf-heatmap-color: var(--color-semantic-action-primary);
384
+ --pf-heatmap-empty: var(--color-semantic-background-subtle);
385
+ --pf-heatmap-label-color: var(--color-semantic-text-muted);
386
+ --pf-heatmap-cell-radius: var(--radius-sm);
387
+
364
388
  /* GaugeChart aliases */
365
389
  --pf-gauge-color: var(--color-semantic-action-primary);
366
390
  --pf-gauge-track-color: var(--color-semantic-background-subtle);
@@ -400,6 +424,9 @@
400
424
  --pf-notification-text: var(--color-semantic-text-default);
401
425
  --pf-notification-text-muted: var(--color-semantic-text-muted);
402
426
  --pf-notification-bg-subtle: var(--color-semantic-background-subtle);
427
+ /* Surface the variant tints blend toward; white in light, a dark raised
428
+ surface in dark so cards stay dark and text keeps contrast. */
429
+ --pf-notification-mix-base: var(--color-base-white);
403
430
  --pf-notification-info-bg: var(--color-brand-50);
404
431
  --pf-notification-info-border: var(--color-brand-300);
405
432
  --pf-notification-info-icon: var(--color-brand-700);
@@ -697,6 +724,7 @@
697
724
  --color-semantic-status-danger-bright: var(--color-danger-400);
698
725
 
699
726
  /* Info state overrides — light brand colors (brand-50/100/300) are invisible on dark surfaces */
727
+ --pf-notification-mix-base: var(--color-semantic-background-raised);
700
728
  --pf-notification-info-bg: var(--color-brand-900);
701
729
  --pf-notification-info-border: var(--color-brand-700);
702
730
  --pf-notification-info-icon: var(--color-brand-300);
@@ -735,6 +763,12 @@
735
763
  /* GaugeChart — track uses background-subtle (gray-700) which is 1.72:1 against gray-900 */
736
764
  --pf-gauge-track-color: var(--color-semantic-border-strong);
737
765
 
766
+ /* ProgressSteps — semantic success bg shades flip in dark mode, so the marker
767
+ numbers need opposite text colors to keep ≥4.5:1.
768
+ complete: white on success-700 = 5.4:1; current: success-900 on success-300 = 6.4:1 */
769
+ --pf-progress-steps-complete-text: var(--color-base-white);
770
+ --pf-progress-steps-current-text: var(--color-success-900);
771
+
738
772
  /* TreeView — border-default (gray-700) is 1.73:1 against gray-900, fails WCAG non-text contrast.
739
773
  border-strong (gray-500) gives 3.75:1. */
740
774
  --pf-treeview-border: var(--color-semantic-border-strong);
@@ -783,6 +817,91 @@ body {
783
817
  vertical-align: var(--pf-icon-vertical-align, middle);
784
818
  color: var(--pf-icon-color, currentColor);
785
819
  }
820
+ .pf-accordion {
821
+ border: 1px solid var(--pf-accordion-border);
822
+ border-radius: var(--radius-md);
823
+ overflow: hidden;
824
+ }
825
+
826
+ .pf-accordion__item + .pf-accordion__item {
827
+ border-top: 1px solid var(--pf-accordion-border);
828
+ }
829
+
830
+ .pf-accordion__heading {
831
+ margin: 0;
832
+ font-size: inherit;
833
+ font-weight: inherit;
834
+ }
835
+
836
+ .pf-accordion__trigger {
837
+ align-items: center;
838
+ background: transparent;
839
+ border: 0;
840
+ color: var(--pf-accordion-trigger-text);
841
+ cursor: pointer;
842
+ display: flex;
843
+ font: inherit;
844
+ font-weight: var(--font-weight-medium);
845
+ gap: var(--space-3);
846
+ justify-content: space-between;
847
+ padding: var(--space-3) var(--space-4);
848
+ text-align: start;
849
+ width: 100%;
850
+ }
851
+
852
+ .pf-accordion__trigger:hover:not(:disabled) {
853
+ background: var(--pf-accordion-trigger-bg-hover);
854
+ }
855
+
856
+ .pf-accordion__trigger:focus-visible {
857
+ box-shadow: var(--pf-focus-ring);
858
+ outline: none;
859
+ }
860
+
861
+ .pf-accordion__trigger:disabled {
862
+ cursor: not-allowed;
863
+ opacity: 0.5;
864
+ }
865
+
866
+ .pf-accordion__icon {
867
+ align-items: center;
868
+ color: var(--pf-accordion-icon);
869
+ display: inline-flex;
870
+ flex-shrink: 0;
871
+ transition: transform var(--pf-transition-fast);
872
+ }
873
+
874
+ .pf-accordion__item--open .pf-accordion__icon {
875
+ transform: rotate(180deg);
876
+ }
877
+
878
+ /* Animate open/close height with the grid-template-rows 0fr → 1fr technique */
879
+ .pf-accordion__panel {
880
+ display: grid;
881
+ grid-template-rows: 0fr;
882
+ transition: grid-template-rows var(--pf-transition-medium);
883
+ }
884
+
885
+ .pf-accordion__panel--open {
886
+ grid-template-rows: 1fr;
887
+ }
888
+
889
+ .pf-accordion__content {
890
+ min-height: 0;
891
+ overflow: hidden;
892
+ color: var(--pf-accordion-content-text);
893
+ }
894
+
895
+ .pf-accordion__content-inner {
896
+ padding: 0 var(--space-4) var(--space-4);
897
+ }
898
+
899
+ @media (prefers-reduced-motion: reduce) {
900
+ .pf-accordion__panel,
901
+ .pf-accordion__icon {
902
+ transition: none;
903
+ }
904
+ }
786
905
  .pf-alert {
787
906
  align-items: flex-start;
788
907
  border: 1px solid var(--pf-alert-border);
@@ -858,7 +977,7 @@ body {
858
977
  display: inline-flex;
859
978
  font-size: var(--font-size-md);
860
979
  justify-content: center;
861
- margin-left: auto;
980
+ margin-inline-start: auto;
862
981
  padding: 0;
863
982
  }
864
983
 
@@ -866,6 +985,34 @@ body {
866
985
  box-shadow: var(--pf-alert-focus-ring, var(--pf-focus-ring));
867
986
  outline: none;
868
987
  }
988
+
989
+ /* Exit: fade and collapse so surrounding content reflows when dismissed. */
990
+ .pf-alert--exiting {
991
+ animation: pf-alert-out var(--duration-moderate) var(--easing-accelerate) forwards;
992
+ overflow: hidden;
993
+ pointer-events: none;
994
+ }
995
+
996
+ @keyframes pf-alert-out {
997
+ from {
998
+ opacity: 1;
999
+ max-height: 480px;
1000
+ }
1001
+ to {
1002
+ opacity: 0;
1003
+ max-height: 0;
1004
+ margin-top: 0;
1005
+ margin-bottom: 0;
1006
+ padding-top: 0;
1007
+ padding-bottom: 0;
1008
+ }
1009
+ }
1010
+
1011
+ @media (prefers-reduced-motion: reduce) {
1012
+ .pf-alert--exiting {
1013
+ animation: none;
1014
+ }
1015
+ }
869
1016
  .pf-avatar {
870
1017
  --pf-avatar-status-size: 10px;
871
1018
  --pf-avatar-status-offset: -2px;
@@ -943,7 +1090,7 @@ body {
943
1090
  top: var(--pf-avatar-status-offset);
944
1091
  height: var(--pf-avatar-status-size, 10px);
945
1092
  position: absolute;
946
- right: var(--pf-avatar-status-offset);
1093
+ inset-inline-end: var(--pf-avatar-status-offset);
947
1094
  width: var(--pf-avatar-status-size, 10px);
948
1095
  z-index: 1;
949
1096
  }
@@ -977,10 +1124,10 @@ body {
977
1124
  min-height: 40px;
978
1125
  text-decoration: none;
979
1126
  transition:
980
- background-color 120ms ease,
981
- border-color 120ms ease,
982
- color 120ms ease,
983
- box-shadow 120ms ease;
1127
+ background-color var(--pf-transition-fast),
1128
+ border-color var(--pf-transition-fast),
1129
+ color var(--pf-transition-fast),
1130
+ box-shadow var(--pf-transition-fast);
984
1131
  }
985
1132
 
986
1133
  .pf-button:focus-visible {
@@ -1084,13 +1231,13 @@ body {
1084
1231
  }
1085
1232
 
1086
1233
  .pf-badge-group--leading .pf-badge-group__text {
1087
- margin-left: -1px;
1088
- padding-left: calc(var(--space-2) + 2px);
1234
+ margin-inline-start: -1px;
1235
+ padding-inline-start: calc(var(--space-2) + 2px);
1089
1236
  }
1090
1237
 
1091
1238
  .pf-badge-group--trailing .pf-badge-group__text {
1092
- margin-right: -1px;
1093
- padding-right: calc(var(--space-2) + 2px);
1239
+ margin-inline-end: -1px;
1240
+ padding-inline-end: calc(var(--space-2) + 2px);
1094
1241
  }
1095
1242
 
1096
1243
  .pf-badge-group--leading .pf-badge-group__badge {
@@ -1187,7 +1334,7 @@ body {
1187
1334
  gap: var(--space-2);
1188
1335
  justify-content: center;
1189
1336
  line-height: 1;
1190
- margin-left: -1px;
1337
+ margin-inline-start: -1px;
1191
1338
  min-height: 40px;
1192
1339
  padding: 0 var(--space-4);
1193
1340
  position: relative;
@@ -1201,7 +1348,7 @@ body {
1201
1348
  .pf-button-group__button:first-child {
1202
1349
  border-bottom-left-radius: var(--radius-md);
1203
1350
  border-top-left-radius: var(--radius-md);
1204
- margin-left: 0;
1351
+ margin-inline-start: 0;
1205
1352
  }
1206
1353
 
1207
1354
  .pf-button-group__button:last-child {
@@ -1691,7 +1838,7 @@ body {
1691
1838
  color: var(--pf-dropdown-text-muted);
1692
1839
  display: inline-flex;
1693
1840
  height: var(--pf-dropdown-icon-size);
1694
- transition: transform 140ms ease;
1841
+ transition: transform var(--pf-transition-fast);
1695
1842
  width: var(--pf-dropdown-icon-size);
1696
1843
  }
1697
1844
 
@@ -1715,6 +1862,19 @@ body {
1715
1862
  padding: var(--space-1);
1716
1863
  position: fixed;
1717
1864
  z-index: 1000;
1865
+ transform-origin: top center;
1866
+ animation: pf-dropdown-menu-in var(--duration-fast) var(--easing-decelerate);
1867
+ }
1868
+
1869
+ @keyframes pf-dropdown-menu-in {
1870
+ from {
1871
+ opacity: 0;
1872
+ transform: translateY(-4px) scale(0.97);
1873
+ }
1874
+ to {
1875
+ opacity: 1;
1876
+ transform: translateY(0) scale(1);
1877
+ }
1718
1878
  }
1719
1879
 
1720
1880
  .pf-dropdown__item {
@@ -1729,7 +1889,7 @@ body {
1729
1889
  justify-content: space-between;
1730
1890
  min-height: 34px;
1731
1891
  padding: 0 var(--space-2);
1732
- text-align: left;
1892
+ text-align: start;
1733
1893
  width: 100%;
1734
1894
  }
1735
1895
 
@@ -1779,6 +1939,10 @@ body {
1779
1939
  .pf-dropdown__chevron {
1780
1940
  transition: none;
1781
1941
  }
1942
+
1943
+ .pf-dropdown__menu {
1944
+ animation: none;
1945
+ }
1782
1946
  }
1783
1947
  .pf-calendar {
1784
1948
  background: var(--pf-calendar-bg);
@@ -1944,7 +2108,8 @@ body {
1944
2108
 
1945
2109
  .pf-carousel__track {
1946
2110
  display: flex;
1947
- transition: transform var(--pf-carousel-transition-duration, 180ms) ease-out;
2111
+ transition: transform var(--pf-carousel-transition-duration, var(--duration-moderate))
2112
+ var(--easing-decelerate);
1948
2113
  width: 100%;
1949
2114
  }
1950
2115
 
@@ -2021,7 +2186,8 @@ body {
2021
2186
  cursor: pointer;
2022
2187
  height: var(--pf-carousel-indicator-size, 8px);
2023
2188
  padding: 0;
2024
- transition: all var(--pf-carousel-indicator-transition-duration, 120ms) ease-out;
2189
+ transition: all var(--pf-carousel-indicator-transition-duration, var(--duration-fast))
2190
+ var(--easing-decelerate);
2025
2191
  width: var(--pf-carousel-indicator-size, 8px);
2026
2192
  }
2027
2193
 
@@ -2180,8 +2346,8 @@ body {
2180
2346
  .pf-code-snippet__line-number {
2181
2347
  color: var(--pf-code-snippet-line-number, var(--color-gray-400));
2182
2348
  min-width: 2.5ch;
2183
- padding-right: var(--space-3);
2184
- text-align: right;
2349
+ padding-inline-end: var(--space-3);
2350
+ text-align: end;
2185
2351
  user-select: none;
2186
2352
  vertical-align: top;
2187
2353
  }
@@ -2210,8 +2376,8 @@ body {
2210
2376
  }
2211
2377
 
2212
2378
  .pf-content-divider--inset {
2213
- padding-left: var(--space-2);
2214
- padding-right: var(--space-2);
2379
+ padding-inline-start: var(--space-2);
2380
+ padding-inline-end: var(--space-2);
2215
2381
  }
2216
2382
 
2217
2383
  .pf-content-divider__line {
@@ -2258,7 +2424,7 @@ body {
2258
2424
  min-height: 40px;
2259
2425
  min-width: 0;
2260
2426
  padding: 0 var(--space-3);
2261
- text-align: left;
2427
+ text-align: start;
2262
2428
  }
2263
2429
 
2264
2430
  .pf-date-picker__trigger:hover:not(:disabled) {
@@ -2633,6 +2799,64 @@ body {
2633
2799
  gap: var(--space-3);
2634
2800
  grid-template-columns: auto 1fr;
2635
2801
  padding: var(--space-3);
2802
+ position: relative;
2803
+ }
2804
+
2805
+ /* Leave room for the centered dismiss button so content/action don't crowd it */
2806
+ .pf-inline-cta--dismissible {
2807
+ padding-inline-end: var(--space-12);
2808
+ }
2809
+
2810
+ .pf-inline-cta__dismiss {
2811
+ align-items: center;
2812
+ background: transparent;
2813
+ border: 0;
2814
+ border-radius: var(--radius-sm);
2815
+ color: var(--color-semantic-text-muted);
2816
+ cursor: pointer;
2817
+ display: inline-flex;
2818
+ height: 28px;
2819
+ justify-content: center;
2820
+ position: absolute;
2821
+ inset-inline-end: var(--space-3);
2822
+ top: 50%;
2823
+ transform: translateY(-50%);
2824
+ width: 28px;
2825
+ }
2826
+
2827
+ .pf-inline-cta__dismiss:hover,
2828
+ .pf-inline-cta__dismiss:focus-visible {
2829
+ background: var(--color-semantic-background-subtle);
2830
+ color: var(--color-semantic-text-default);
2831
+ outline: none;
2832
+ }
2833
+
2834
+ /* Exit: fade and collapse so surrounding content reflows when dismissed. */
2835
+ .pf-inline-cta--exiting {
2836
+ animation: pf-inline-cta-out var(--duration-moderate) var(--easing-accelerate) forwards;
2837
+ overflow: hidden;
2838
+ pointer-events: none;
2839
+ }
2840
+
2841
+ @keyframes pf-inline-cta-out {
2842
+ from {
2843
+ opacity: 1;
2844
+ max-height: 480px;
2845
+ }
2846
+ to {
2847
+ opacity: 0;
2848
+ max-height: 0;
2849
+ margin-top: 0;
2850
+ margin-bottom: 0;
2851
+ padding-top: 0;
2852
+ padding-bottom: 0;
2853
+ }
2854
+ }
2855
+
2856
+ @media (prefers-reduced-motion: reduce) {
2857
+ .pf-inline-cta--exiting {
2858
+ animation: none;
2859
+ }
2636
2860
  }
2637
2861
 
2638
2862
  @media (min-width: 768px) {
@@ -2727,7 +2951,24 @@ body {
2727
2951
  }
2728
2952
 
2729
2953
  .pf-gauge__fill {
2730
- transition: stroke-dasharray var(--pf-transition-medium, 180ms ease);
2954
+ stroke-dashoffset: var(--pf-gauge-offset);
2955
+ /* Animate the arc filling from empty to its value on mount, and smoothly
2956
+ when the value changes afterward. */
2957
+ animation: pf-gauge-fill var(--duration-slow) var(--easing-decelerate);
2958
+ transition: stroke-dashoffset var(--pf-transition-medium);
2959
+ }
2960
+
2961
+ @keyframes pf-gauge-fill {
2962
+ from {
2963
+ stroke-dashoffset: var(--pf-gauge-circumference);
2964
+ }
2965
+ }
2966
+
2967
+ @media (prefers-reduced-motion: reduce) {
2968
+ .pf-gauge__fill {
2969
+ animation: none;
2970
+ transition: none;
2971
+ }
2731
2972
  }
2732
2973
 
2733
2974
  .pf-gauge__center {
@@ -2756,6 +2997,106 @@ body {
2756
2997
  font-size: var(--font-size-sm);
2757
2998
  line-height: 1;
2758
2999
  }
3000
+ .pf-heatmap {
3001
+ display: inline-block;
3002
+ font-family: var(--font-family-sans);
3003
+ }
3004
+
3005
+ .pf-heatmap__empty {
3006
+ color: var(--color-semantic-text-muted);
3007
+ font-size: var(--font-size-sm);
3008
+ padding: var(--space-4);
3009
+ text-align: center;
3010
+ }
3011
+
3012
+ .pf-heatmap__body {
3013
+ display: flex;
3014
+ gap: var(--pf-heatmap-cell-gap);
3015
+ }
3016
+
3017
+ .pf-heatmap__weekdays {
3018
+ display: flex;
3019
+ flex-direction: column;
3020
+ }
3021
+
3022
+ .pf-heatmap__weekday-spacer {
3023
+ display: block;
3024
+ height: calc(var(--font-size-xs) + var(--space-1));
3025
+ }
3026
+
3027
+ .pf-heatmap__weekday-grid {
3028
+ display: grid;
3029
+ grid-template-rows: repeat(7, var(--pf-heatmap-cell-size));
3030
+ gap: var(--pf-heatmap-cell-gap);
3031
+ }
3032
+
3033
+ .pf-heatmap__weekday {
3034
+ align-items: center;
3035
+ color: var(--pf-heatmap-label-color);
3036
+ display: flex;
3037
+ font-size: var(--font-size-xs);
3038
+ line-height: 1;
3039
+ padding-inline-end: var(--space-1);
3040
+ }
3041
+
3042
+ .pf-heatmap__main {
3043
+ display: flex;
3044
+ flex-direction: column;
3045
+ gap: var(--space-1);
3046
+ }
3047
+
3048
+ .pf-heatmap__months {
3049
+ display: grid;
3050
+ gap: var(--pf-heatmap-cell-gap);
3051
+ height: var(--font-size-xs);
3052
+ }
3053
+
3054
+ .pf-heatmap__month {
3055
+ color: var(--pf-heatmap-label-color);
3056
+ font-size: var(--font-size-xs);
3057
+ line-height: 1;
3058
+ }
3059
+
3060
+ .pf-heatmap__grid {
3061
+ display: grid;
3062
+ grid-template-rows: repeat(7, var(--pf-heatmap-cell-size));
3063
+ grid-auto-flow: column;
3064
+ grid-auto-columns: var(--pf-heatmap-cell-size);
3065
+ gap: var(--pf-heatmap-cell-gap);
3066
+ }
3067
+
3068
+ .pf-heatmap__cell {
3069
+ border-radius: var(--pf-heatmap-cell-radius);
3070
+ height: var(--pf-heatmap-cell-size);
3071
+ width: var(--pf-heatmap-cell-size);
3072
+ }
3073
+
3074
+ .pf-heatmap__cell--empty {
3075
+ background: transparent;
3076
+ }
3077
+
3078
+ /* Staggered fade-in on mount — per-column animation-delay is set inline so
3079
+ the grid wipes in left-to-right (oldest week → newest). */
3080
+ .pf-heatmap__cell {
3081
+ animation: pf-heatmap-cell-in var(--duration-moderate) var(--easing-decelerate) both;
3082
+ }
3083
+
3084
+ @keyframes pf-heatmap-cell-in {
3085
+ from {
3086
+ opacity: 0;
3087
+ transform: scale(0.6);
3088
+ }
3089
+ to {
3090
+ opacity: 1;
3091
+ transform: scale(1);
3092
+ }
3093
+ }
3094
+
3095
+ @media (prefers-reduced-motion: reduce) {
3096
+ .pf-heatmap__cell {
3097
+ animation: none;
3098
+ }
3099
+ }
2759
3100
  /* ─── Chart color palette ─────────────────────────────────────────────── */
2760
3101
  :root {
2761
3102
  --pf-chart-color-1: var(--color-brand-600);
@@ -3182,6 +3523,8 @@ body {
3182
3523
  }
3183
3524
 
3184
3525
  .pf-modal__body {
3526
+ display: grid;
3527
+ gap: var(--space-4);
3185
3528
  overflow-y: auto;
3186
3529
  padding: var(--space-3);
3187
3530
  }
@@ -3227,6 +3570,66 @@ body {
3227
3570
  color: var(--pf-modal-text);
3228
3571
  outline: none;
3229
3572
  }
3573
+
3574
+ /* Entrance animation — uses motion tokens via theme aliases */
3575
+ @keyframes pf-modal-overlay-in {
3576
+ from {
3577
+ opacity: 0;
3578
+ }
3579
+ to {
3580
+ opacity: 1;
3581
+ }
3582
+ }
3583
+
3584
+ @keyframes pf-modal-in {
3585
+ from {
3586
+ opacity: 0;
3587
+ transform: translateY(8px) scale(0.98);
3588
+ }
3589
+ to {
3590
+ opacity: 1;
3591
+ transform: translateY(0) scale(1);
3592
+ }
3593
+ }
3594
+
3595
+ .pf-modal__overlay {
3596
+ animation: pf-modal-overlay-in var(--pf-transition-fast);
3597
+ }
3598
+
3599
+ .pf-modal {
3600
+ animation: pf-modal-in var(--pf-transition-enter);
3601
+ }
3602
+
3603
+ /* Exit animation — plays while the dialog is being dismissed (presence handling) */
3604
+ @keyframes pf-modal-overlay-out {
3605
+ to {
3606
+ opacity: 0;
3607
+ }
3608
+ }
3609
+
3610
+ @keyframes pf-modal-out {
3611
+ to {
3612
+ opacity: 0;
3613
+ transform: translateY(8px) scale(0.98);
3614
+ }
3615
+ }
3616
+
3617
+ .pf-modal__overlay--exiting {
3618
+ animation: pf-modal-overlay-out var(--pf-transition-fast) forwards;
3619
+ }
3620
+
3621
+ .pf-modal--exiting {
3622
+ animation: pf-modal-out var(--pf-transition-fast) forwards;
3623
+ }
3624
+
3625
+ @media (prefers-reduced-motion: reduce) {
3626
+ .pf-modal__overlay,
3627
+ .pf-modal,
3628
+ .pf-modal__overlay--exiting,
3629
+ .pf-modal--exiting {
3630
+ animation: none;
3631
+ }
3632
+ }
3230
3633
  .pf-multi-select {
3231
3634
  position: relative;
3232
3635
  }
@@ -3244,7 +3647,7 @@ body {
3244
3647
  justify-content: space-between;
3245
3648
  min-height: 40px;
3246
3649
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-2);
3247
- text-align: left;
3650
+ text-align: start;
3248
3651
  width: 100%;
3249
3652
  transition:
3250
3653
  background 0.2s,
@@ -3307,7 +3710,7 @@ body {
3307
3710
  justify-content: center;
3308
3711
  width: 20px;
3309
3712
  transform-origin: center;
3310
- transition: transform 140ms ease;
3713
+ transition: transform var(--pf-transition-fast);
3311
3714
  }
3312
3715
 
3313
3716
  .pf-multi-select__icon svg {
@@ -3332,6 +3735,19 @@ body {
3332
3735
  padding: var(--space-1);
3333
3736
  position: fixed;
3334
3737
  z-index: 1000;
3738
+ transform-origin: top center;
3739
+ animation: pf-multi-select-menu-in var(--duration-fast) var(--easing-decelerate);
3740
+ }
3741
+
3742
+ @keyframes pf-multi-select-menu-in {
3743
+ from {
3744
+ opacity: 0;
3745
+ transform: translateY(-4px) scaleY(0.96);
3746
+ }
3747
+ to {
3748
+ opacity: 1;
3749
+ transform: translateY(0) scaleY(1);
3750
+ }
3335
3751
  }
3336
3752
 
3337
3753
  .pf-multi-select__option {
@@ -3383,6 +3799,10 @@ body {
3383
3799
  .pf-multi-select__icon {
3384
3800
  transition: none;
3385
3801
  }
3802
+
3803
+ .pf-multi-select__menu {
3804
+ animation: none;
3805
+ }
3386
3806
  }
3387
3807
  .pf-notification-stack {
3388
3808
  display: grid;
@@ -3445,6 +3865,45 @@ body {
3445
3865
  max-width: none;
3446
3866
  padding: var(--space-3);
3447
3867
  width: 100%;
3868
+ animation: pf-notification-in var(--duration-moderate) var(--easing-decelerate);
3869
+ }
3870
+
3871
+ @keyframes pf-notification-in {
3872
+ from {
3873
+ opacity: 0;
3874
+ transform: translateX(12px);
3875
+ }
3876
+ }
3877
+
3878
+ /* Exit: slide off to the right and collapse so stacked siblings reflow. */
3879
+ .pf-notification--exiting {
3880
+ animation: pf-notification-out var(--duration-moderate) var(--easing-accelerate) forwards;
3881
+ overflow: hidden;
3882
+ pointer-events: none;
3883
+ }
3884
+
3885
+ @keyframes pf-notification-out {
3886
+ from {
3887
+ opacity: 1;
3888
+ transform: translateX(0);
3889
+ max-height: 480px;
3890
+ }
3891
+ to {
3892
+ opacity: 0;
3893
+ transform: translateX(100%);
3894
+ max-height: 0;
3895
+ margin-top: 0;
3896
+ margin-bottom: 0;
3897
+ padding-top: 0;
3898
+ padding-bottom: 0;
3899
+ }
3900
+ }
3901
+
3902
+ @media (prefers-reduced-motion: reduce) {
3903
+ .pf-notification,
3904
+ .pf-notification--exiting {
3905
+ animation: none;
3906
+ }
3448
3907
  }
3449
3908
 
3450
3909
  @media (min-width: 768px) {
@@ -3455,22 +3914,38 @@ body {
3455
3914
  }
3456
3915
 
3457
3916
  .pf-notification--info {
3458
- background: color-mix(in srgb, var(--pf-notification-info-bg) 45%, var(--color-base-white));
3917
+ background: color-mix(
3918
+ in srgb,
3919
+ var(--pf-notification-info-bg) 45%,
3920
+ var(--pf-notification-mix-base)
3921
+ );
3459
3922
  border-color: var(--pf-notification-info-border);
3460
3923
  }
3461
3924
 
3462
3925
  .pf-notification--success {
3463
- background: color-mix(in srgb, var(--pf-notification-success-bg) 45%, var(--color-base-white));
3926
+ background: color-mix(
3927
+ in srgb,
3928
+ var(--pf-notification-success-bg) 45%,
3929
+ var(--pf-notification-mix-base)
3930
+ );
3464
3931
  border-color: var(--pf-notification-success-border);
3465
3932
  }
3466
3933
 
3467
3934
  .pf-notification--warning {
3468
- background: color-mix(in srgb, var(--pf-notification-warning-bg) 45%, var(--color-base-white));
3935
+ background: color-mix(
3936
+ in srgb,
3937
+ var(--pf-notification-warning-bg) 45%,
3938
+ var(--pf-notification-mix-base)
3939
+ );
3469
3940
  border-color: var(--pf-notification-warning-border);
3470
3941
  }
3471
3942
 
3472
3943
  .pf-notification--danger {
3473
- background: color-mix(in srgb, var(--pf-notification-danger-bg) 45%, var(--color-base-white));
3944
+ background: color-mix(
3945
+ in srgb,
3946
+ var(--pf-notification-danger-bg) 45%,
3947
+ var(--pf-notification-mix-base)
3948
+ );
3474
3949
  border-color: var(--pf-notification-danger-border);
3475
3950
  }
3476
3951
 
@@ -3780,6 +4255,38 @@ body {
3780
4255
  position: relative;
3781
4256
  }
3782
4257
 
4258
+ /* The conic-gradient lives on a masked layer so it can sweep ("build out")
4259
+ clockwise on mount without clipping the center label. */
4260
+ @property --pf-pie-sweep {
4261
+ syntax: '<percentage>';
4262
+ inherits: false;
4263
+ initial-value: 0%;
4264
+ }
4265
+
4266
+ .pf-pie-chart__visual::before {
4267
+ content: '';
4268
+ position: absolute;
4269
+ inset: 0;
4270
+ border-radius: inherit;
4271
+ background-image: var(--pf-pie-gradient);
4272
+ --pf-pie-sweep: 100%;
4273
+ -webkit-mask: conic-gradient(#000 var(--pf-pie-sweep), #0000 0);
4274
+ mask: conic-gradient(#000 var(--pf-pie-sweep), #0000 0);
4275
+ animation: pf-pie-sweep var(--duration-slow) var(--easing-decelerate);
4276
+ }
4277
+
4278
+ @keyframes pf-pie-sweep {
4279
+ from {
4280
+ --pf-pie-sweep: 0%;
4281
+ }
4282
+ }
4283
+
4284
+ @media (prefers-reduced-motion: reduce) {
4285
+ .pf-pie-chart__visual::before {
4286
+ animation: none;
4287
+ }
4288
+ }
4289
+
3783
4290
  .pf-pie-chart__visual--empty {
3784
4291
  outline: 1px solid var(--pf-piechart-border-muted);
3785
4292
  }
@@ -3794,6 +4301,8 @@ body {
3794
4301
  font-weight: var(--font-weight-semibold);
3795
4302
  justify-content: center;
3796
4303
  line-height: 1.2;
4304
+ position: relative;
4305
+ z-index: 1;
3797
4306
  text-align: center;
3798
4307
  }
3799
4308
 
@@ -3858,8 +4367,16 @@ body {
3858
4367
  background: var(--pf-progress-accent);
3859
4368
  border-radius: inherit;
3860
4369
  height: 100%;
3861
- transition: width 200ms ease;
3862
4370
  width: var(--pf-progress-fill, 0%);
4371
+ /* Animate fill in from 0 on mount, and smoothly between values on change */
4372
+ transition: width var(--pf-transition-slow);
4373
+ animation: pf-progress-bar-in var(--duration-slow) var(--easing-decelerate);
4374
+ }
4375
+
4376
+ @keyframes pf-progress-bar-in {
4377
+ from {
4378
+ width: 0;
4379
+ }
3863
4380
  }
3864
4381
 
3865
4382
  .pf-progress-bar__value {
@@ -3896,7 +4413,16 @@ body {
3896
4413
  .pf-progress-circle__fill {
3897
4414
  stroke: var(--pf-progress-accent);
3898
4415
  stroke-linecap: round;
3899
- transition: stroke-dashoffset 200ms ease;
4416
+ stroke-dashoffset: var(--pf-progress-dashoffset);
4417
+ /* Animate fill in from empty on mount, and smoothly between values on change */
4418
+ transition: stroke-dashoffset var(--pf-transition-slow);
4419
+ animation: pf-progress-circle-in var(--duration-slow) var(--easing-decelerate);
4420
+ }
4421
+
4422
+ @keyframes pf-progress-circle-in {
4423
+ from {
4424
+ stroke-dashoffset: var(--pf-progress-circ);
4425
+ }
3900
4426
  }
3901
4427
 
3902
4428
  .pf-progress-circle__value {
@@ -3913,6 +4439,7 @@ body {
3913
4439
  .pf-progress-bar__fill,
3914
4440
  .pf-progress-circle__fill {
3915
4441
  transition: none;
4442
+ animation: none;
3916
4443
  }
3917
4444
  }
3918
4445
  .pf-progress-steps {
@@ -3979,13 +4506,21 @@ body {
3979
4506
  width: 28px;
3980
4507
  position: relative;
3981
4508
  z-index: 1;
4509
+ /* Animate marker as its status changes when the current step advances */
4510
+ transition:
4511
+ background-color var(--pf-transition-medium),
4512
+ border-color var(--pf-transition-medium),
4513
+ color var(--pf-transition-medium),
4514
+ box-shadow var(--pf-transition-medium);
3982
4515
  }
3983
4516
 
3984
4517
  .pf-progress-steps__connector {
3985
4518
  background: var(--pf-progress-steps-border);
3986
4519
  display: block;
3987
4520
  flex: 1;
3988
- margin-left: var(--space-2);
4521
+ margin-inline-start: var(--space-2);
4522
+ /* Connector "activates" with a smooth fill as the step completes */
4523
+ transition: background-color var(--pf-transition-slow);
3989
4524
  }
3990
4525
 
3991
4526
  .pf-progress-steps--horizontal .pf-progress-steps__connector {
@@ -3997,7 +4532,7 @@ body {
3997
4532
  display: block;
3998
4533
  height: 1px;
3999
4534
  left: 50%;
4000
- margin-left: 0;
4535
+ margin-inline-start: 0;
4001
4536
  position: absolute;
4002
4537
  top: 50%;
4003
4538
  transform: translateY(-50%);
@@ -4028,7 +4563,7 @@ body {
4028
4563
 
4029
4564
  .pf-progress-steps--vertical .pf-progress-steps__connector {
4030
4565
  bottom: calc(var(--space-3) * -1);
4031
- left: 14px;
4566
+ inset-inline-start: 14px;
4032
4567
  margin: 0;
4033
4568
  position: absolute;
4034
4569
  top: 28px;
@@ -4044,6 +4579,7 @@ body {
4044
4579
  font-size: var(--font-size-sm);
4045
4580
  font-weight: var(--font-weight-semibold);
4046
4581
  margin: var(--space-1) 0 0;
4582
+ transition: color var(--pf-transition-medium);
4047
4583
  }
4048
4584
 
4049
4585
  .pf-progress-steps__description {
@@ -4073,6 +4609,14 @@ body {
4073
4609
  .pf-progress-steps__item--current .pf-progress-steps__title {
4074
4610
  color: var(--pf-progress-steps-current-title);
4075
4611
  }
4612
+
4613
+ @media (prefers-reduced-motion: reduce) {
4614
+ .pf-progress-steps__marker,
4615
+ .pf-progress-steps__connector,
4616
+ .pf-progress-steps__title {
4617
+ transition: none;
4618
+ }
4619
+ }
4076
4620
  .pf-radar-chart {
4077
4621
  align-items: stretch;
4078
4622
  display: inline-flex;
@@ -4170,6 +4714,28 @@ body {
4170
4714
  padding: var(--space-4);
4171
4715
  text-align: center;
4172
4716
  }
4717
+
4718
+ /* Grow the value polygon out from the center on mount */
4719
+ .pf-radar-chart__value {
4720
+ animation: pf-radar-grow var(--duration-slow) var(--easing-decelerate);
4721
+ }
4722
+
4723
+ @keyframes pf-radar-grow {
4724
+ from {
4725
+ opacity: 0;
4726
+ transform: scale(0);
4727
+ }
4728
+ to {
4729
+ opacity: 1;
4730
+ transform: scale(1);
4731
+ }
4732
+ }
4733
+
4734
+ @media (prefers-reduced-motion: reduce) {
4735
+ .pf-radar-chart__value {
4736
+ animation: none;
4737
+ }
4738
+ }
4173
4739
  .pf-radio-field {
4174
4740
  align-items: center;
4175
4741
  display: inline-flex;
@@ -4438,7 +5004,7 @@ body {
4438
5004
  color: var(--pf-rte-text-muted);
4439
5005
  font-size: var(--font-size-sm);
4440
5006
  margin: var(--space-2) 0 0;
4441
- text-align: right;
5007
+ text-align: end;
4442
5008
  }
4443
5009
  .pf-section-footer {
4444
5010
  align-items: flex-start;
@@ -4655,7 +5221,7 @@ body {
4655
5221
  grid-template-columns: auto 1fr auto;
4656
5222
  min-height: 36px;
4657
5223
  padding: 0 var(--space-2);
4658
- text-align: left;
5224
+ text-align: start;
4659
5225
  text-decoration: none;
4660
5226
  width: 100%;
4661
5227
  }
@@ -4710,6 +5276,54 @@ body {
4710
5276
  .pf-sparkline__dot {
4711
5277
  fill: var(--pf-sparkline-color-override, var(--pf-sparkline-color));
4712
5278
  }
5279
+
5280
+ /* Opt-in mount animation: draw the line, fade in the area and end dot.
5281
+ The line path sets pathLength="1" so dash math is length-independent. */
5282
+ .pf-sparkline--animated .pf-sparkline__line {
5283
+ stroke-dasharray: 1;
5284
+ animation: pf-sparkline-draw var(--duration-slow) var(--easing-standard) both;
5285
+ }
5286
+
5287
+ @keyframes pf-sparkline-draw {
5288
+ from {
5289
+ stroke-dashoffset: 1;
5290
+ }
5291
+ to {
5292
+ stroke-dashoffset: 0;
5293
+ }
5294
+ }
5295
+
5296
+ .pf-sparkline--animated .pf-sparkline__area {
5297
+ animation: pf-sparkline-fade var(--duration-slow) var(--easing-standard) both;
5298
+ }
5299
+
5300
+ @keyframes pf-sparkline-fade {
5301
+ from {
5302
+ opacity: 0;
5303
+ }
5304
+ }
5305
+
5306
+ .pf-sparkline--animated .pf-sparkline__dot {
5307
+ animation: pf-sparkline-dot var(--duration-fast) var(--easing-decelerate) var(--duration-moderate)
5308
+ both;
5309
+ }
5310
+
5311
+ @keyframes pf-sparkline-dot {
5312
+ from {
5313
+ opacity: 0;
5314
+ }
5315
+ to {
5316
+ opacity: 1;
5317
+ }
5318
+ }
5319
+
5320
+ @media (prefers-reduced-motion: reduce) {
5321
+ .pf-sparkline--animated .pf-sparkline__line,
5322
+ .pf-sparkline--animated .pf-sparkline__area,
5323
+ .pf-sparkline--animated .pf-sparkline__dot {
5324
+ animation: none;
5325
+ }
5326
+ }
4713
5327
  .pf-slideout__portal {
4714
5328
  inset: 0;
4715
5329
  position: fixed;
@@ -4721,7 +5335,7 @@ body {
4721
5335
  opacity: 1;
4722
5336
  inset: 0;
4723
5337
  position: absolute;
4724
- transition: opacity 220ms ease;
5338
+ transition: opacity var(--pf-transition-slow);
4725
5339
  }
4726
5340
 
4727
5341
  .pf-slideout__viewport {
@@ -4750,7 +5364,7 @@ body {
4750
5364
  height: 100%;
4751
5365
  max-width: 100%;
4752
5366
  pointer-events: auto;
4753
- transition: transform 220ms ease;
5367
+ transition: transform var(--pf-transition-slow);
4754
5368
  will-change: transform;
4755
5369
  }
4756
5370
 
@@ -4947,7 +5561,7 @@ body {
4947
5561
  justify-content: space-between;
4948
5562
  min-height: 40px;
4949
5563
  padding: 0 var(--space-3);
4950
- text-align: left;
5564
+ text-align: start;
4951
5565
  width: 100%;
4952
5566
  transition:
4953
5567
  background 0.2s,
@@ -5001,7 +5615,7 @@ body {
5001
5615
  justify-content: center;
5002
5616
  width: 20px;
5003
5617
  transform-origin: center;
5004
- transition: transform 140ms ease;
5618
+ transition: transform var(--pf-transition-fast);
5005
5619
  }
5006
5620
 
5007
5621
  .pf-select__icon svg {
@@ -5026,6 +5640,25 @@ body {
5026
5640
  padding: var(--space-1);
5027
5641
  position: fixed;
5028
5642
  z-index: 1000;
5643
+ transform-origin: top center;
5644
+ animation: pf-select-menu-in var(--duration-fast) var(--easing-decelerate);
5645
+ }
5646
+
5647
+ @keyframes pf-select-menu-in {
5648
+ from {
5649
+ opacity: 0;
5650
+ transform: translateY(-4px) scaleY(0.96);
5651
+ }
5652
+ to {
5653
+ opacity: 1;
5654
+ transform: translateY(0) scaleY(1);
5655
+ }
5656
+ }
5657
+
5658
+ @media (prefers-reduced-motion: reduce) {
5659
+ .pf-select__menu {
5660
+ animation: none;
5661
+ }
5029
5662
  }
5030
5663
 
5031
5664
  .pf-select__option {
@@ -5218,7 +5851,7 @@ body {
5218
5851
  display: inline-flex;
5219
5852
  height: 18px;
5220
5853
  justify-content: center;
5221
- margin-right: -2px;
5854
+ margin-inline-end: -2px;
5222
5855
  padding: 0;
5223
5856
  width: 18px;
5224
5857
  }
@@ -5259,9 +5892,9 @@ body {
5259
5892
  font-size: var(--font-size-sm);
5260
5893
  min-height: 56px;
5261
5894
  padding-top: var(--space-3);
5262
- padding-right: var(--space-4, 16px);
5895
+ padding-inline-end: var(--space-4, 16px);
5263
5896
  padding-bottom: var(--space-3);
5264
- padding-left: var(--space-4, 16px);
5897
+ padding-inline-start: var(--space-4, 16px);
5265
5898
  }
5266
5899
 
5267
5900
  .pf-table__head-cell,
@@ -5342,7 +5975,7 @@ body {
5342
5975
  }
5343
5976
 
5344
5977
  .pf-table__cell--left {
5345
- text-align: left;
5978
+ text-align: start;
5346
5979
  }
5347
5980
 
5348
5981
  .pf-table__cell--center {
@@ -5350,7 +5983,7 @@ body {
5350
5983
  }
5351
5984
 
5352
5985
  .pf-table__cell--right {
5353
- text-align: right;
5986
+ text-align: end;
5354
5987
  }
5355
5988
 
5356
5989
  .pf-table__empty {
@@ -5377,6 +6010,31 @@ body {
5377
6010
  .pf-tabs__list {
5378
6011
  display: flex;
5379
6012
  overflow-x: auto;
6013
+ position: relative;
6014
+ }
6015
+
6016
+ .pf-tabs__indicator {
6017
+ position: absolute;
6018
+ pointer-events: none;
6019
+ transition:
6020
+ left var(--pf-transition-medium),
6021
+ width var(--pf-transition-medium),
6022
+ top var(--pf-transition-medium),
6023
+ height var(--pf-transition-medium);
6024
+ }
6025
+
6026
+ .pf-tabs__indicator--underline {
6027
+ bottom: 0;
6028
+ height: var(--pf-tabs-underline-width);
6029
+ background: var(--pf-tabs-text);
6030
+ border-radius: var(--radius-full);
6031
+ }
6032
+
6033
+ .pf-tabs__indicator--pills {
6034
+ background: var(--pf-tabs-bg);
6035
+ border-radius: var(--radius-sm);
6036
+ box-shadow: var(--pf-tabs-elevation-tab-active-shadow, var(--pf-elevation-tab-active-shadow));
6037
+ z-index: 0;
5380
6038
  }
5381
6039
 
5382
6040
  .pf-tabs__list--full-width {
@@ -5405,7 +6063,8 @@ body {
5405
6063
  font-weight: var(--font-weight-medium);
5406
6064
  min-width: 0;
5407
6065
  position: relative;
5408
- transition: color 160ms ease;
6066
+ z-index: 1;
6067
+ transition: color var(--pf-transition-medium);
5409
6068
  white-space: nowrap;
5410
6069
  }
5411
6070
 
@@ -5440,7 +6099,7 @@ body {
5440
6099
  }
5441
6100
 
5442
6101
  .pf-tabs__tab--underline.pf-tabs__tab--active {
5443
- border-bottom-color: var(--pf-tabs-text);
6102
+ /* The sliding indicator draws the underline; keep the transparent border for spacing */
5444
6103
  color: var(--pf-tabs-text);
5445
6104
  }
5446
6105
 
@@ -5454,8 +6113,7 @@ body {
5454
6113
  }
5455
6114
 
5456
6115
  .pf-tabs__tab--pills.pf-tabs__tab--active {
5457
- background: var(--pf-tabs-bg);
5458
- box-shadow: var(--pf-tabs-elevation-tab-active-shadow, var(--pf-elevation-tab-active-shadow));
6116
+ /* The sliding indicator draws the pill background */
5459
6117
  color: var(--pf-tabs-text);
5460
6118
  }
5461
6119
 
@@ -5471,7 +6129,8 @@ body {
5471
6129
  }
5472
6130
 
5473
6131
  @media (prefers-reduced-motion: reduce) {
5474
- .pf-tabs__tab {
6132
+ .pf-tabs__tab,
6133
+ .pf-tabs__indicator {
5475
6134
  transition: none;
5476
6135
  }
5477
6136
  }
@@ -5553,6 +6212,41 @@ body {
5553
6212
  position: fixed;
5554
6213
  z-index: 1100;
5555
6214
  }
6215
+
6216
+ /* Entrance animation — uses motion tokens via theme aliases */
6217
+ @keyframes pf-tooltip-in {
6218
+ from {
6219
+ opacity: 0;
6220
+ transform: translateY(2px);
6221
+ }
6222
+ to {
6223
+ opacity: 1;
6224
+ transform: translateY(0);
6225
+ }
6226
+ }
6227
+
6228
+ .pf-tooltip {
6229
+ animation: pf-tooltip-in var(--pf-transition-fast);
6230
+ }
6231
+
6232
+ /* Exit fade — plays while the tooltip is dismissed (presence handling) */
6233
+ @keyframes pf-tooltip-out {
6234
+ to {
6235
+ opacity: 0;
6236
+ transform: translateY(2px);
6237
+ }
6238
+ }
6239
+
6240
+ .pf-tooltip--exiting {
6241
+ animation: pf-tooltip-out var(--duration-fast) var(--easing-accelerate) forwards;
6242
+ }
6243
+
6244
+ @media (prefers-reduced-motion: reduce) {
6245
+ .pf-tooltip,
6246
+ .pf-tooltip--exiting {
6247
+ animation: none;
6248
+ }
6249
+ }
5556
6250
  .pf-tree-view {
5557
6251
  background: var(--pf-treeview-bg);
5558
6252
  border: 1px solid var(--pf-treeview-border);
@@ -5575,7 +6269,7 @@ body {
5575
6269
  display: grid;
5576
6270
  grid-template-columns: auto 1fr;
5577
6271
  min-width: 0;
5578
- padding-left: calc(var(--pf-tree-level, 0) * var(--space-4));
6272
+ padding-inline-start: calc(var(--pf-tree-level, 0) * var(--space-4));
5579
6273
  }
5580
6274
 
5581
6275
  .pf-tree-view__toggle-wrap {
@@ -5624,7 +6318,7 @@ body {
5624
6318
  min-height: 34px;
5625
6319
  min-width: 0;
5626
6320
  padding: 0 var(--space-2);
5627
- text-align: left;
6321
+ text-align: start;
5628
6322
  width: 100%;
5629
6323
  }
5630
6324