@xenide-io/the-old-ui-theme 0.9.18 → 0.11.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 (79) hide show
  1. package/dist/{Chip-BzuNgJIa.d.mts → Chip-Dw2g2t8D.d.mts} +18 -4
  2. package/dist/{Chip-BzuNgJIa.d.ts → Chip-Dw2g2t8D.d.ts} +18 -4
  3. package/dist/{chunk-6SVJAU5K.mjs → chunk-RIPGN6FG.mjs} +1333 -526
  4. package/dist/index.d.mts +3 -2
  5. package/dist/index.d.ts +3 -2
  6. package/dist/index.js +490 -119
  7. package/dist/index.mjs +11 -3
  8. package/dist/suite-analytics--Mf1RZbw.d.mts +29 -0
  9. package/dist/suite-analytics--Mf1RZbw.d.ts +29 -0
  10. package/dist/suite.d.mts +36 -4
  11. package/dist/suite.d.ts +36 -4
  12. package/dist/suite.js +4617 -4001
  13. package/dist/suite.mjs +1456 -868
  14. package/dist/tailwind-preset.js +10 -1
  15. package/dist/tailwind-preset.mjs +10 -1
  16. package/dist/ui.d.mts +33 -4
  17. package/dist/ui.d.ts +33 -4
  18. package/dist/ui.js +1364 -571
  19. package/dist/ui.mjs +15 -1
  20. package/docs/macos-identity-audit.md +279 -0
  21. package/package.json +1 -1
  22. package/src/app/globals.css +390 -44
  23. package/src/components/ui/Accordion.tsx +4 -7
  24. package/src/components/ui/Avatar.tsx +5 -5
  25. package/src/components/ui/BrandSpinner.tsx +256 -0
  26. package/src/components/ui/Calendar.tsx +7 -7
  27. package/src/components/ui/CodeBlock.tsx +14 -11
  28. package/src/components/ui/CollapsibleSection.tsx +4 -4
  29. package/src/components/ui/CommandPalette.tsx +7 -10
  30. package/src/components/ui/EmptyState.tsx +2 -2
  31. package/src/components/ui/Input.tsx +1 -1
  32. package/src/components/ui/Marketing.tsx +144 -0
  33. package/src/components/ui/MarketingIllustrations.tsx +287 -0
  34. package/src/components/ui/Panel.tsx +1 -1
  35. package/src/components/ui/SegmentedControl.tsx +59 -13
  36. package/src/components/ui/SettingsLayout.tsx +4 -0
  37. package/src/components/ui/ShowcaseWrapper.tsx +3 -3
  38. package/src/components/ui/Table.tsx +45 -10
  39. package/src/components/ui/Typography.tsx +4 -4
  40. package/src/components/ui/avatar-stat.test.tsx +14 -1
  41. package/src/components/ui/brand-spinner.test.tsx +62 -0
  42. package/src/components/ui/index.ts +19 -11
  43. package/src/components/ui/interaction-primitives.test.tsx +12 -6
  44. package/src/components/ui/marketing.test.tsx +39 -0
  45. package/src/components/ui/table.test.tsx +47 -0
  46. package/src/styles/suite-skin.css +471 -74
  47. package/src/styles/themes.css +45 -45
  48. package/src/styles/typography.css +25 -1
  49. package/src/suite/components/ai-draft-editor.tsx +184 -0
  50. package/src/suite/components/ai-panel-workflows.test.tsx +179 -0
  51. package/src/suite/components/ai-panel.tsx +201 -31
  52. package/src/suite/components/app-switcher.tsx +22 -9
  53. package/src/suite/components/command-palette-host.tsx +20 -2
  54. package/src/suite/components/suite-app-layout.tsx +7 -4
  55. package/src/suite/components/suite-bottom-nav.tsx +1 -1
  56. package/src/suite/components/suite-clients-projects-directory.tsx +6 -6
  57. package/src/suite/components/suite-integration-picker.tsx +7 -7
  58. package/src/suite/components/suite-integration-rules.tsx +5 -5
  59. package/src/suite/components/suite-layout.test.tsx +32 -3
  60. package/src/suite/components/suite-layout.tsx +4 -4
  61. package/src/suite/components/suite-mobile-drawer.tsx +2 -2
  62. package/src/suite/components/suite-mobile-header.tsx +1 -1
  63. package/src/suite/components/suite-notification-bell.tsx +27 -6
  64. package/src/suite/components/suite-notification-settings.tsx +182 -0
  65. package/src/suite/components/suite-palette-library.test.tsx +46 -0
  66. package/src/suite/components/suite-palette-library.tsx +82 -15
  67. package/src/suite/components/suite-settings-layout.tsx +2 -2
  68. package/src/suite/components/suite-settings-mobile-nav.tsx +10 -10
  69. package/src/suite/components/suite-sidebar.test.tsx +39 -0
  70. package/src/suite/components/suite-sidebar.tsx +41 -19
  71. package/src/suite/components/suite-skeleton.tsx +6 -6
  72. package/src/suite/components/suite-user-menu.tsx +2 -2
  73. package/src/suite/components/theme-provider.tsx +2 -0
  74. package/src/suite/components/today-calibrating.tsx +3 -3
  75. package/src/suite/components/today-ui.tsx +42 -37
  76. package/src/suite/components/workspace-switcher.tsx +3 -3
  77. package/src/suite/index.ts +14 -0
  78. package/src/suite/lib/suite-notifications.tsx +5 -0
  79. package/tailwind-preset.ts +9 -0
@@ -44,7 +44,7 @@
44
44
  --ph-chrome-inset-solid-bottom: inset 0 -1px 0 hsl(0deg 0% 0% / 0.14);
45
45
  --ph-radius-app: 0.375rem;
46
46
  --ph-radius-control: var(--ph-radius-app);
47
- --ph-radius-surface: 0.5rem;
47
+ --ph-radius-surface: 0.625rem;
48
48
  --ph-radius-overlay: 0.75rem;
49
49
  --ph-border-control: color-mix(in oklab, var(--ph-border) 68%, var(--ph-border-strong));
50
50
  /** Tailwind `ph.brand` maps to `--ph-accent`; plain CSS controls used only this name, so it must exist. */
@@ -77,8 +77,10 @@
77
77
  --ph-danger-bg: color-mix(in oklab, var(--ph-danger) 12%, var(--ph-surface));
78
78
  --ph-danger-border: color-mix(in oklab, var(--ph-danger) 45%, var(--ph-border));
79
79
  --ph-danger-text: color-mix(in oklab, var(--ph-danger) 76%, var(--ph-text-primary));
80
- --ph-shadow-raised: 0 1px 2px hsl(0deg 0% 0% / 0.08), 0 3px 8px hsl(0deg 0% 0% / 0.06);
81
- --ph-shadow-floating: 0 18px 48px hsl(0deg 0% 0% / 0.22), 0 2px 8px hsl(0deg 0% 0% / 0.12);
80
+ --ph-shadow-raised: 0 1px 2px hsl(0deg 0% 0% / 0.08), 0 4px 12px hsl(0deg 0% 0% / 0.06);
81
+ --ph-shadow-floating: 0 18px 48px hsl(0deg 0% 0% / 0.2), 0 2px 8px hsl(0deg 0% 0% / 0.1);
82
+ --ph-shadow-control: 0 1px 2px hsl(0deg 0% 0% / 0.1), inset 0 1px 0 hsl(0deg 0% 100% / 0.38);
83
+ --ph-focus-halo: 0 0 0 3px color-mix(in oklab, var(--ph-focus-ring) 30%, transparent);
82
84
  --ph-motion-fast: 120ms;
83
85
  --ph-motion-standard: 180ms;
84
86
  }
@@ -104,21 +106,42 @@ html {
104
106
 
105
107
  body {
106
108
  @apply bg-ph-canvas text-ph-ink antialiased;
107
- font-size: 15px;
108
- line-height: 1.5;
109
+ font-family: var(--ph-font-sans-stack);
110
+ font-size: var(--ph-type-body);
111
+ line-height: var(--ph-leading-body);
109
112
  }
110
113
 
111
114
  @layer components {
115
+ .suite-sidebar-link:focus-visible {
116
+ outline: none;
117
+ box-shadow: var(--ph-focus-halo);
118
+ }
119
+
120
+ .ph-brand-spinner__column {
121
+ animation: ph-spinner-columns 0.85s ease-in-out infinite;
122
+ }
123
+
124
+ @keyframes ph-spinner-columns {
125
+ 0%, 100% { opacity: 0.35; transform: translateY(2px); }
126
+ 50% { opacity: 1; transform: translateY(-2px); }
127
+ }
128
+
129
+ .ph-page-title {
130
+ font-size: var(--ph-type-page);
131
+ line-height: var(--ph-leading-title);
132
+ letter-spacing: -0.025em;
133
+ text-wrap: balance;
134
+ }
112
135
  /**
113
136
  * PostHog LemonButton — from frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss
114
137
  */
115
138
  .ph-btn {
116
- --ph-btn-control-size: 2.3125rem;
139
+ --ph-btn-control-size: 2.5rem;
117
140
  @apply inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap font-medium;
118
141
  border-radius: var(--ph-radius-control);
119
- min-height: 2.3125rem;
142
+ min-height: var(--ph-btn-control-size);
120
143
  padding: 0.25rem 0.875rem;
121
- font-size: 0.875rem;
144
+ font-size: var(--ph-type-ui);
122
145
  line-height: 1.5rem;
123
146
  transition:
124
147
  transform var(--ph-motion-fast) ease,
@@ -131,27 +154,27 @@ body {
131
154
  }
132
155
 
133
156
  .ph-btn:focus-visible {
134
- outline: 3px solid color-mix(in oklab, var(--ph-focus-ring) 38%, transparent);
135
- outline-offset: 2px;
157
+ outline: none;
158
+ box-shadow: var(--ph-focus-halo);
136
159
  }
137
160
 
138
161
  .ph-btn-sm {
139
- --ph-btn-control-size: 2.0625rem;
140
- min-height: 2.0625rem;
162
+ --ph-btn-control-size: 2.125rem;
163
+ min-height: var(--ph-btn-control-size);
141
164
  padding: 0.25rem 0.625rem;
142
- font-size: 0.8125rem;
165
+ font-size: var(--ph-type-meta);
143
166
  }
144
167
 
145
168
  .ph-btn-xs {
146
- --ph-btn-control-size: 1.625rem;
147
- min-height: 1.625rem;
169
+ --ph-btn-control-size: 1.75rem;
170
+ min-height: var(--ph-btn-control-size);
148
171
  padding: 0.125rem 0.5rem;
149
- font-size: 0.6875rem;
172
+ font-size: var(--ph-type-overline);
150
173
  }
151
174
 
152
175
  .ph-btn-lg {
153
- --ph-btn-control-size: 3.0625rem;
154
- min-height: 3.0625rem;
176
+ --ph-btn-control-size: 3rem;
177
+ min-height: var(--ph-btn-control-size);
155
178
  padding: 0.375rem 1.25rem;
156
179
  font-size: 1rem;
157
180
  }
@@ -305,7 +328,7 @@ body {
305
328
  justify-content: center;
306
329
  gap: inherit;
307
330
  width: 100%;
308
- min-height: 2.3125rem;
331
+ min-height: var(--ph-btn-control-size);
309
332
  padding:
310
333
  calc(0.25rem - var(--ph-btn-chrome-depth) * 0.5) 0.875rem
311
334
  calc(0.25rem + var(--ph-btn-chrome-depth) * 0.5);
@@ -336,25 +359,25 @@ body {
336
359
 
337
360
  .ph-btn-sm.ph-btn-raised .ph-btn-chrome,
338
361
  .ph-btn-sm:is(.ph-btn-primary, .ph-btn-secondary, .ph-btn-signal, .ph-btn-accent, .ph-btn-neutral, .ph-btn-info, .ph-btn-success, .ph-btn-warning, .ph-btn-danger):not(:has(.ph-btn-chrome)) {
339
- min-height: 2.0625rem;
362
+ min-height: var(--ph-btn-control-size);
340
363
  padding:
341
364
  calc(0.25rem - var(--ph-btn-chrome-depth) * 0.5) 0.625rem
342
365
  calc(0.25rem + var(--ph-btn-chrome-depth) * 0.5);
343
- font-size: 0.8125rem;
366
+ font-size: var(--ph-type-meta);
344
367
  }
345
368
 
346
369
  .ph-btn-xs.ph-btn-raised .ph-btn-chrome,
347
370
  .ph-btn-xs:is(.ph-btn-primary, .ph-btn-secondary, .ph-btn-signal, .ph-btn-accent, .ph-btn-neutral, .ph-btn-info, .ph-btn-success, .ph-btn-warning, .ph-btn-danger):not(:has(.ph-btn-chrome)) {
348
- min-height: 1.625rem;
371
+ min-height: var(--ph-btn-control-size);
349
372
  padding:
350
373
  calc(0.125rem - var(--ph-btn-chrome-depth) * 0.5) 0.5rem
351
374
  calc(0.125rem + var(--ph-btn-chrome-depth) * 0.5);
352
- font-size: 0.6875rem;
375
+ font-size: var(--ph-type-overline);
353
376
  }
354
377
 
355
378
  .ph-btn-lg.ph-btn-raised .ph-btn-chrome,
356
379
  .ph-btn-lg:is(.ph-btn-primary, .ph-btn-secondary, .ph-btn-signal, .ph-btn-accent, .ph-btn-neutral, .ph-btn-info, .ph-btn-success, .ph-btn-warning, .ph-btn-danger):not(:has(.ph-btn-chrome)) {
357
- min-height: 3.0625rem;
380
+ min-height: var(--ph-btn-control-size);
358
381
  padding:
359
382
  calc(0.375rem - var(--ph-btn-chrome-depth) * 0.5) 1.25rem
360
383
  calc(0.375rem + var(--ph-btn-chrome-depth) * 0.5);
@@ -539,6 +562,7 @@ body {
539
562
  background: var(--ph-btn-face);
540
563
  border: var(--ph-btn-border-width) solid var(--ph-btn-border);
541
564
  border-radius: var(--ph-radius-control);
565
+ box-shadow: var(--ph-chrome-inset-solid-top);
542
566
  transform: translateY(var(--ph-btn-face-offset));
543
567
  transition:
544
568
  border-color var(--ph-motion-fast) ease,
@@ -585,9 +609,7 @@ body {
585
609
  @apply border bg-ph-muted p-6;
586
610
  border-radius: var(--ph-radius-surface);
587
611
  border-color: var(--ph-border-control);
588
- box-shadow:
589
- var(--ph-chrome-inset-face-top),
590
- var(--ph-shadow-elevation-3000);
612
+ box-shadow: var(--ph-chrome-inset-face-top);
591
613
  }
592
614
 
593
615
  .ph-card {
@@ -692,7 +714,8 @@ body {
692
714
  background: var(--ph-surface-raised);
693
715
  border-radius: var(--ph-radius-control);
694
716
  border: 1px solid var(--ph-border-control);
695
- min-height: 2.3125rem;
717
+ min-height: 2.5rem;
718
+ font-size: var(--ph-type-ui);
696
719
  line-height: 1.5rem;
697
720
  font-family: inherit;
698
721
  box-shadow:
@@ -705,7 +728,7 @@ body {
705
728
  .ph-textarea:focus-visible {
706
729
  outline: none;
707
730
  box-shadow:
708
- 0 0 0 3px color-mix(in oklab, var(--ph-focus-ring) 24%, transparent),
731
+ var(--ph-focus-halo),
709
732
  var(--ph-chrome-inset-face-top),
710
733
  var(--ph-chrome-inset-face-bottom);
711
734
  border-color: color-mix(in oklab, var(--ph-focus-ring) 58%, var(--ph-border));
@@ -715,6 +738,22 @@ body {
715
738
  @apply ph-input-base;
716
739
  }
717
740
 
741
+ .ph-field-icon-button {
742
+ @apply absolute inset-y-0 right-0 flex w-10 items-center justify-center text-ph-mutedtext disabled:opacity-40;
743
+ border-radius: 0 var(--ph-radius-control) var(--ph-radius-control) 0;
744
+ transition: color var(--ph-motion-fast) ease;
745
+ }
746
+
747
+ .ph-field-icon-button:hover:not(:disabled) {
748
+ color: var(--ph-text-primary);
749
+ }
750
+
751
+ .ph-field-icon-button:focus-visible {
752
+ z-index: 1;
753
+ outline: none;
754
+ box-shadow: var(--ph-focus-halo);
755
+ }
756
+
718
757
  .ph-input-error:focus-visible,
719
758
  .ph-select.ph-input-error:focus-visible,
720
759
  .ph-textarea.ph-input-error:focus-visible {
@@ -737,7 +776,7 @@ body {
737
776
  .ph-input-sm {
738
777
  min-height: 1.875rem;
739
778
  padding-block: 0.125rem;
740
- font-size: 0.8125rem;
779
+ font-size: var(--ph-type-meta);
741
780
  }
742
781
 
743
782
  .ph-input-lg {
@@ -792,7 +831,7 @@ body {
792
831
  .ph-search-group__submit .ph-btn-chrome {
793
832
  box-sizing: border-box;
794
833
  height: 100%;
795
- min-height: 2.3125rem;
834
+ min-height: 2.5rem;
796
835
  padding-left: 0.75rem;
797
836
  padding-right: 0.75rem;
798
837
  }
@@ -824,6 +863,13 @@ body {
824
863
  min-height: 6rem;
825
864
  }
826
865
 
866
+ @media (pointer: coarse) {
867
+ .ph-input,
868
+ .ph-select {
869
+ min-height: 2.75rem;
870
+ }
871
+ }
872
+
827
873
  .ph-checkbox,
828
874
  .ph-radio {
829
875
  @apply shrink-0 cursor-pointer appearance-none transition;
@@ -865,7 +911,7 @@ body {
865
911
  .ph-toggle:focus-visible {
866
912
  outline: none;
867
913
  box-shadow:
868
- 0 0 0 3px color-mix(in oklab, var(--ph-accent) 18%, transparent),
914
+ var(--ph-focus-halo),
869
915
  var(--ph-chrome-inset-face-top),
870
916
  var(--ph-chrome-inset-face-bottom);
871
917
  }
@@ -951,20 +997,67 @@ body {
951
997
  }
952
998
 
953
999
  /* LemonTable.scss — sticky-header border Simulation + row rhythm */
1000
+ .ph-table-report-wrap {
1001
+ overflow-x: auto;
1002
+ }
1003
+
1004
+ .ph-table-report-wrap:focus-visible {
1005
+ outline: 3px solid color-mix(in oklab, var(--ph-focus-ring) 30%, transparent);
1006
+ outline-offset: 2px;
1007
+ }
1008
+
1009
+ /* Preserve the existing report table geometry and sentence-case headings. */
1010
+ .ph-table-report {
1011
+ @apply w-full text-left text-sm;
1012
+ }
1013
+
1014
+ .ph-table-report thead {
1015
+ color: var(--ph-text-secondary);
1016
+ }
1017
+
1018
+ .ph-table-report tr {
1019
+ border-bottom: 1px solid var(--ph-border);
1020
+ }
1021
+
1022
+ .ph-table-report th:first-child,
1023
+ .ph-table-report td:first-child {
1024
+ padding-block: 0.75rem;
1025
+ }
1026
+
1027
+ .ph-table-report th:not(:last-child),
1028
+ .ph-table-report td:not(:last-child) {
1029
+ padding-right: 1rem;
1030
+ }
1031
+
1032
+ .ph-table-compact .ph-table-report {
1033
+ font-size: var(--ph-type-meta);
1034
+ }
1035
+
1036
+ .ph-table-compact .ph-table-report th:first-child,
1037
+ .ph-table-compact .ph-table-report td:first-child {
1038
+ padding-block: 0.375rem;
1039
+ }
1040
+
954
1041
  .ph-table-wrap {
955
1042
  @apply overflow-x-auto bg-ph-surface;
956
- border-radius: var(--ph-radius-app);
1043
+ border-radius: var(--ph-radius-surface);
957
1044
  border: 1px solid var(--ph-border);
958
- box-shadow: var(--ph-shadow-elevation-3000);
1045
+ box-shadow: none;
1046
+ }
1047
+
1048
+ .ph-table-wrap:focus-visible {
1049
+ outline: none;
1050
+ border-color: color-mix(in oklab, var(--ph-focus-ring) 58%, var(--ph-border));
1051
+ box-shadow: var(--ph-focus-halo);
959
1052
  }
960
1053
 
961
1054
  .ph-table {
962
1055
  @apply w-full border-collapse text-left;
963
- font-size: 13px;
1056
+ font-size: var(--ph-type-small);
964
1057
  }
965
1058
 
966
1059
  .ph-table thead {
967
- background: var(--ph-surface);
1060
+ background: var(--ph-surface-inset);
968
1061
  color: var(--ph-text-tertiary);
969
1062
  }
970
1063
 
@@ -972,8 +1065,8 @@ body {
972
1065
  @apply whitespace-nowrap px-2 py-2;
973
1066
  padding-left: 1rem;
974
1067
  padding-right: 1rem;
975
- font-size: 0.75rem;
976
- font-weight: 700;
1068
+ font-size: var(--ph-type-meta);
1069
+ font-weight: 600;
977
1070
  text-transform: uppercase;
978
1071
  letter-spacing: 0.03125rem;
979
1072
  box-shadow: inset 0 -1px var(--ph-border);
@@ -985,6 +1078,7 @@ body {
985
1078
  padding-right: 1rem;
986
1079
  vertical-align: middle;
987
1080
  color: var(--ph-text-secondary);
1081
+ padding-block: 0.625rem;
988
1082
  }
989
1083
 
990
1084
  .ph-table tbody tr + tr td {
@@ -1020,7 +1114,152 @@ body {
1020
1114
  }
1021
1115
 
1022
1116
  .ph-table-compact .ph-table td {
1023
- @apply py-1 text-[12px];
1117
+ @apply py-1.5;
1118
+ font-size: var(--ph-type-meta);
1119
+ }
1120
+
1121
+ .ph-table td.ph-table-empty,
1122
+ .ph-table-report td.ph-table-empty {
1123
+ @apply py-8 text-center text-sm text-ph-mutedtext;
1124
+ }
1125
+
1126
+ .ph-table--ribbon tbody td.ph-table-empty::before {
1127
+ content: none;
1128
+ }
1129
+
1130
+ .ph-avatar {
1131
+ box-shadow: var(--ph-chrome-inset-solid-top);
1132
+ }
1133
+
1134
+ .ph-empty-state {
1135
+ @apply flex flex-col items-center justify-center border border-dashed px-8 py-16 text-center;
1136
+ border-color: var(--ph-border-subtle);
1137
+ border-radius: var(--ph-radius-surface);
1138
+ background: var(--ph-surface-inset);
1139
+ }
1140
+
1141
+ .ph-empty-state__icon {
1142
+ @apply mb-4 flex h-14 w-14 items-center justify-center rounded-full text-ph-mutedtext;
1143
+ background: var(--ph-surface-raised);
1144
+ box-shadow: var(--ph-chrome-inset-solid-top);
1145
+ }
1146
+
1147
+ .ph-accordion {
1148
+ @apply overflow-hidden border bg-ph-surface;
1149
+ border-color: var(--ph-border-subtle);
1150
+ border-radius: var(--ph-radius-surface);
1151
+ }
1152
+
1153
+ .ph-accordion__item + .ph-accordion__item {
1154
+ border-top: 1px solid var(--ph-border-subtle);
1155
+ }
1156
+
1157
+ .ph-accordion__trigger,
1158
+ .ph-collapsible-trigger {
1159
+ @apply flex w-full items-center justify-between px-5 py-4 text-left;
1160
+ color: var(--ph-text-primary);
1161
+ transition: background-color var(--ph-motion-fast) ease;
1162
+ }
1163
+
1164
+ .ph-accordion__trigger:hover,
1165
+ .ph-collapsible-trigger:hover {
1166
+ background: var(--ph-surface-hover);
1167
+ }
1168
+
1169
+ .ph-accordion__trigger:focus-visible {
1170
+ outline: 3px solid color-mix(in oklab, var(--ph-focus-ring) 30%, transparent);
1171
+ outline-offset: -3px;
1172
+ }
1173
+
1174
+ .ph-collapsible-trigger {
1175
+ border: 1px solid var(--ph-border-subtle);
1176
+ border-radius: var(--ph-radius-surface);
1177
+ background: var(--ph-surface-inset);
1178
+ }
1179
+
1180
+ .ph-collapsible-trigger:focus-visible,
1181
+ .ph-showcase-toggle:focus-visible {
1182
+ outline: none;
1183
+ box-shadow: var(--ph-focus-halo);
1184
+ }
1185
+
1186
+ .ph-calendar {
1187
+ border: 1px solid var(--ph-border-control);
1188
+ border-radius: var(--ph-radius-overlay);
1189
+ background: color-mix(in oklab, var(--ph-surface-overlay) 94%, transparent);
1190
+ -webkit-backdrop-filter: blur(24px) saturate(1.2);
1191
+ backdrop-filter: blur(24px) saturate(1.2);
1192
+ box-shadow:
1193
+ var(--ph-chrome-inset-face-top),
1194
+ var(--ph-shadow-floating);
1195
+ }
1196
+
1197
+ .ph-calendar__nav {
1198
+ @apply flex h-9 w-9 items-center justify-center text-ph-subtle;
1199
+ border-radius: var(--ph-radius-control);
1200
+ transition:
1201
+ color var(--ph-motion-fast) ease,
1202
+ background-color var(--ph-motion-fast) ease;
1203
+ }
1204
+
1205
+ .ph-calendar__nav:hover {
1206
+ color: var(--ph-text-primary);
1207
+ background: var(--ph-surface-hover);
1208
+ }
1209
+
1210
+ .ph-calendar__nav:focus-visible,
1211
+ .ph-calendar__day:focus-visible {
1212
+ z-index: 1;
1213
+ outline: none;
1214
+ box-shadow: var(--ph-focus-halo);
1215
+ }
1216
+
1217
+ .ph-calendar__day {
1218
+ @apply flex h-full w-full items-center justify-center text-sm text-ph-ink;
1219
+ border-radius: var(--ph-radius-control);
1220
+ transition:
1221
+ color var(--ph-motion-fast) ease,
1222
+ background-color var(--ph-motion-fast) ease,
1223
+ box-shadow var(--ph-motion-fast) ease;
1224
+ }
1225
+
1226
+ .ph-calendar__day:hover {
1227
+ background: var(--ph-surface-hover);
1228
+ }
1229
+
1230
+ .ph-calendar__day--selected {
1231
+ color: var(--ph-on-accent);
1232
+ background: var(--ph-brand);
1233
+ box-shadow: var(--ph-shadow-control);
1234
+ font-weight: 600;
1235
+ }
1236
+
1237
+ .ph-calendar__day--today:not(.ph-calendar__day--selected) {
1238
+ color: var(--ph-selected-text);
1239
+ background: var(--ph-selected-bg);
1240
+ box-shadow: inset 0 0 0 1px var(--ph-selected-border);
1241
+ font-weight: 600;
1242
+ }
1243
+
1244
+ .ph-code-block {
1245
+ @apply overflow-hidden border border-ph-border bg-[#1a1a2e];
1246
+ border-radius: var(--ph-radius-surface);
1247
+ }
1248
+
1249
+ .ph-code-block__copy {
1250
+ @apply text-xs text-white/60;
1251
+ border-radius: var(--ph-radius-control);
1252
+ transition: color var(--ph-motion-fast) ease;
1253
+ }
1254
+
1255
+ .ph-code-block__copy:hover {
1256
+ @apply text-white;
1257
+ }
1258
+
1259
+ .ph-code-block__copy:focus-visible {
1260
+ outline: none;
1261
+ color: white;
1262
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--ph-focus-ring) 55%, transparent);
1024
1263
  }
1025
1264
 
1026
1265
  /* Breadcrumbs */
@@ -1393,7 +1632,9 @@ body {
1393
1632
  overflow:hidden + border-radius, especially at the bottom-right action. */
1394
1633
  overflow: visible;
1395
1634
  overscroll-behavior: contain;
1396
- background: var(--ph-surface-overlay);
1635
+ background: color-mix(in oklab, var(--ph-surface-overlay) 94%, transparent);
1636
+ -webkit-backdrop-filter: blur(24px) saturate(1.2);
1637
+ backdrop-filter: blur(24px) saturate(1.2);
1397
1638
  border-radius: var(--ph-radius-overlay);
1398
1639
  border: 1px solid var(--ph-border-control);
1399
1640
  box-shadow: var(--ph-shadow-floating);
@@ -1432,6 +1673,55 @@ body {
1432
1673
  }
1433
1674
  }
1434
1675
 
1676
+ /* Command palette shares the floating overlay material with menus and modals. */
1677
+ .ph-command-palette__overlay {
1678
+ @apply fixed inset-0 z-50 bg-black/45 backdrop-blur-sm;
1679
+ animation: ph-modal-overlay-in var(--ph-motion-standard) ease-out;
1680
+ }
1681
+
1682
+ .ph-command-palette {
1683
+ @apply fixed left-1/2 top-[20vh] z-50 w-[calc(100%-1rem)] max-w-xl -translate-x-1/2 overflow-hidden;
1684
+ max-height: min(32rem, calc(100dvh - 2rem));
1685
+ border: 1px solid var(--ph-border-control);
1686
+ border-radius: var(--ph-radius-overlay);
1687
+ background: color-mix(in oklab, var(--ph-surface-overlay) 94%, transparent);
1688
+ -webkit-backdrop-filter: blur(24px) saturate(1.2);
1689
+ backdrop-filter: blur(24px) saturate(1.2);
1690
+ box-shadow:
1691
+ var(--ph-chrome-inset-face-top),
1692
+ var(--ph-shadow-floating);
1693
+ animation: ph-command-palette-in var(--ph-motion-standard) cubic-bezier(0.22, 1, 0.36, 1);
1694
+ }
1695
+
1696
+ .ph-command-palette__search {
1697
+ @apply flex items-center gap-3 px-4 py-3;
1698
+ border-bottom: 1px solid var(--ph-border-subtle);
1699
+ background: var(--ph-surface-inset);
1700
+ }
1701
+
1702
+ .ph-command-palette__option {
1703
+ @apply mx-1 flex min-h-9 cursor-pointer items-center gap-3 px-3 py-2 text-left text-sm;
1704
+ width: calc(100% - 0.5rem);
1705
+ border-radius: var(--ph-radius-control);
1706
+ transition:
1707
+ color var(--ph-motion-fast) ease,
1708
+ background-color var(--ph-motion-fast) ease,
1709
+ box-shadow var(--ph-motion-fast) ease;
1710
+ }
1711
+
1712
+ .ph-command-palette__option--selected {
1713
+ color: var(--ph-selected-text);
1714
+ background: var(--ph-selected-bg);
1715
+ box-shadow: inset 0 0 0 1px var(--ph-selected-border);
1716
+ }
1717
+
1718
+ @keyframes ph-command-palette-in {
1719
+ from {
1720
+ opacity: 0;
1721
+ transform: translate(-50%, 0.5rem) scale(0.98);
1722
+ }
1723
+ }
1724
+
1435
1725
  @media (max-width: 40rem) {
1436
1726
  .ph-modal-panel {
1437
1727
  width: calc(100% - 1rem);
@@ -1452,8 +1742,8 @@ body {
1452
1742
  }
1453
1743
 
1454
1744
  .ph-dropdown-trigger:focus-visible {
1455
- outline: 3px solid color-mix(in oklab, var(--ph-focus-ring) 38%, transparent);
1456
- outline-offset: 2px;
1745
+ outline: none;
1746
+ box-shadow: var(--ph-focus-halo);
1457
1747
  }
1458
1748
 
1459
1749
  .ph-dropdown-trigger:disabled {
@@ -1465,11 +1755,14 @@ body {
1465
1755
  }
1466
1756
 
1467
1757
  .ph-dropdown-panel {
1468
- @apply z-50 min-w-[12rem] overflow-y-auto bg-ph-surface p-1;
1758
+ @apply z-50 min-w-[12rem] overflow-y-auto p-1;
1469
1759
  max-width: min(22rem, calc(100vw - 1rem));
1470
1760
  max-height: var(--radix-dropdown-menu-content-available-height);
1471
1761
  border-radius: var(--ph-radius-overlay);
1472
1762
  border: 1px solid var(--ph-border-control);
1763
+ background: color-mix(in oklab, var(--ph-surface-overlay) 94%, transparent);
1764
+ -webkit-backdrop-filter: blur(24px) saturate(1.2);
1765
+ backdrop-filter: blur(24px) saturate(1.2);
1473
1766
  box-shadow:
1474
1767
  var(--ph-chrome-inset-face-top),
1475
1768
  var(--ph-shadow-floating);
@@ -1513,6 +1806,12 @@ body {
1513
1806
  background: var(--ph-surface-hover);
1514
1807
  }
1515
1808
 
1809
+ .ph-dropdown-item:focus-visible {
1810
+ color: var(--ph-selected-text);
1811
+ background: var(--ph-selected-bg);
1812
+ box-shadow: inset 0 0 0 1px var(--ph-selected-border);
1813
+ }
1814
+
1516
1815
  .ph-dropdown-item[data-disabled] {
1517
1816
  @apply pointer-events-none opacity-50;
1518
1817
  }
@@ -1857,6 +2156,52 @@ body {
1857
2156
  }
1858
2157
  }
1859
2158
 
2159
+ /* Segmented control — inset track with one raised selected face. */
2160
+ .ph-segmented-control {
2161
+ display: inline-flex;
2162
+ gap: 2px;
2163
+ padding: 3px;
2164
+ border: 1px solid var(--ph-border-subtle);
2165
+ border-radius: calc(var(--ph-radius-control) + 0.1875rem);
2166
+ background: var(--ph-surface-inset);
2167
+ box-shadow: inset 0 1px 2px hsl(0deg 0% 0% / 0.08);
2168
+ }
2169
+
2170
+ .ph-segmented-control__item {
2171
+ @apply relative flex min-h-11 items-center gap-1.5 px-3.5 py-1.5 text-sm font-medium sm:min-h-9;
2172
+ border: 1px solid transparent;
2173
+ border-radius: var(--ph-radius-control);
2174
+ color: var(--ph-text-secondary);
2175
+ transition:
2176
+ color var(--ph-motion-fast) ease,
2177
+ background-color var(--ph-motion-fast) ease,
2178
+ border-color var(--ph-motion-fast) ease,
2179
+ box-shadow var(--ph-motion-fast) ease,
2180
+ transform 80ms ease-out;
2181
+ }
2182
+
2183
+ .ph-segmented-control__item:hover:not([aria-checked="true"]) {
2184
+ color: var(--ph-text-primary);
2185
+ background: var(--ph-surface-hover);
2186
+ }
2187
+
2188
+ .ph-segmented-control__item[aria-checked="true"] {
2189
+ color: var(--ph-text-primary);
2190
+ border-color: var(--ph-border-subtle);
2191
+ background: var(--ph-surface-raised);
2192
+ box-shadow: var(--ph-shadow-control);
2193
+ }
2194
+
2195
+ .ph-segmented-control__item:active {
2196
+ transform: scale(0.98);
2197
+ }
2198
+
2199
+ .ph-segmented-control__item:focus-visible {
2200
+ z-index: 1;
2201
+ outline: none;
2202
+ box-shadow: var(--ph-focus-halo);
2203
+ }
2204
+
1860
2205
  /* Tabs */
1861
2206
  .ph-tabs-row {
1862
2207
  @apply flex flex-wrap gap-1 rounded-lg bg-ph-muted p-1 border border-ph-border;
@@ -1881,7 +2226,8 @@ body {
1881
2226
  }
1882
2227
 
1883
2228
  .ph-progress-bar {
1884
- @apply h-full rounded-full transition-all duration-300;
2229
+ @apply h-full rounded-full duration-300;
2230
+ transition-property: width;
1885
2231
  }
1886
2232
 
1887
2233
  /* Accessible, collision-aware tooltip overlay. */
@@ -43,22 +43,19 @@ export function Accordion({
43
43
 
44
44
  return (
45
45
  <div
46
- className={cn(
47
- "divide-y divide-ph-border rounded-xl border border-ph-border bg-ph-surface",
48
- className,
49
- )}
46
+ className={cn("ph-accordion", className)}
50
47
  >
51
48
  {items.map((item) => {
52
49
  const isOpen = openItems.has(item.id);
53
50
  const contentId = `accordion-${idPrefix}-${item.id}-content`;
54
51
  return (
55
- <div key={item.id} className="first:rounded-t-xl last:rounded-b-xl">
52
+ <div key={item.id} className="ph-accordion__item">
56
53
  <button
57
54
  type="button"
58
55
  onClick={() => toggleItem(item.id)}
59
56
  aria-expanded={isOpen}
60
57
  aria-controls={contentId}
61
- className="flex w-full items-center justify-between px-5 py-4 text-left transition hover:bg-ph-muted"
58
+ className="ph-accordion__trigger"
62
59
  >
63
60
  <span className="font-semibold text-ph-ink">{item.title}</span>
64
61
  <IconChevronDown
@@ -75,7 +72,7 @@ export function Accordion({
75
72
  if (node) node.toggleAttribute("inert", !isOpen);
76
73
  }}
77
74
  className={cn(
78
- "grid transition-all duration-200",
75
+ "grid transition-[grid-template-rows] duration-200",
79
76
  isOpen ? "grid-rows-[1fr]" : "grid-rows-[0fr]",
80
77
  )}
81
78
  >