@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
package/dist/index.js CHANGED
@@ -68,6 +68,7 @@ __export(src_exports, {
68
68
  Avatar: () => Avatar,
69
69
  AvatarGroup: () => AvatarGroup,
70
70
  Badge: () => Badge,
71
+ BrandSpinner: () => BrandSpinner,
71
72
  Button: () => Button,
72
73
  ButtonChrome: () => ButtonChrome,
73
74
  CANONICAL_ICONS: () => CANONICAL_ICONS,
@@ -192,6 +193,7 @@ __export(src_exports, {
192
193
  Panel: () => Panel,
193
194
  Progress: () => Progress,
194
195
  Radio: () => Radio,
196
+ SUITE_ANALYTICS_EVENT: () => SUITE_ANALYTICS_EVENT,
195
197
  SearchInput: () => SearchInput,
196
198
  SectionTitle: () => SectionTitle,
197
199
  SegmentedControl: () => SegmentedControl,
@@ -218,7 +220,9 @@ __export(src_exports, {
218
220
  getTheme: () => getTheme,
219
221
  isThemeId: () => isThemeId,
220
222
  persistTheme: () => persistTheme,
221
- readStoredTheme: () => readStoredTheme
223
+ readStoredTheme: () => readStoredTheme,
224
+ subscribeSuiteAnalytics: () => subscribeSuiteAnalytics,
225
+ trackSuiteEvent: () => trackSuiteEvent
222
226
  });
223
227
  module.exports = __toCommonJS(src_exports);
224
228
 
@@ -1312,6 +1316,34 @@ function AuthDivider(_a) {
1312
1316
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", __spreadProps(__spreadValues({ className: cn("ph-auth-divider", className) }, props), { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children }) }));
1313
1317
  }
1314
1318
 
1319
+ // src/lib/suite-analytics.ts
1320
+ var SUITE_ANALYTICS_EVENT = "shellstack:analytics";
1321
+ function trackSuiteEvent(event, properties) {
1322
+ if (typeof window === "undefined" || !event) return;
1323
+ try {
1324
+ window.dispatchEvent(
1325
+ new CustomEvent(SUITE_ANALYTICS_EVENT, {
1326
+ detail: { event, properties }
1327
+ })
1328
+ );
1329
+ } catch (e) {
1330
+ }
1331
+ }
1332
+ function subscribeSuiteAnalytics(handler) {
1333
+ if (typeof window === "undefined") return () => {
1334
+ };
1335
+ const listener = (raw) => {
1336
+ const detail = raw.detail;
1337
+ if (!(detail == null ? void 0 : detail.event)) return;
1338
+ try {
1339
+ handler(detail.event, detail.properties);
1340
+ } catch (e) {
1341
+ }
1342
+ };
1343
+ window.addEventListener(SUITE_ANALYTICS_EVENT, listener);
1344
+ return () => window.removeEventListener(SUITE_ANALYTICS_EVENT, listener);
1345
+ }
1346
+
1315
1347
  // src/components/ui/SettingsLayout.tsx
1316
1348
  var import_jsx_runtime12 = require("react/jsx-runtime");
1317
1349
  function SettingsNav(_a) {
@@ -1329,6 +1361,7 @@ function SettingsNav(_a) {
1329
1361
  item.active && "ph-settings-nav__item--active"
1330
1362
  ),
1331
1363
  "aria-current": item.active ? "page" : void 0,
1364
+ onClick: () => trackSuiteEvent("Tab Viewed", { tab: item.id }),
1332
1365
  children: [
1333
1366
  item.icon ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ph-settings-nav__icon", children: item.icon }) : null,
1334
1367
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: item.label }),
@@ -1789,7 +1822,7 @@ var Input = (0, import_react10.forwardRef)(function Input2(_a, ref) {
1789
1822
  "aria-label": revealed ? "Hide password" : "Show password",
1790
1823
  "aria-pressed": revealed,
1791
1824
  disabled,
1792
- className: "absolute inset-y-0 right-0 flex w-10 items-center justify-center rounded-r-[var(--ph-radius-control)] text-ph-mutedtext transition-colors hover:text-ph-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-focus disabled:opacity-40",
1825
+ className: "ph-field-icon-button",
1793
1826
  children: revealed ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_iconoir_react.EyeClosed, { className: "h-4 w-4", "aria-hidden": true }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_iconoir_react.Eye, { className: "h-4 w-4", "aria-hidden": true })
1794
1827
  }
1795
1828
  ) : null
@@ -2179,7 +2212,7 @@ var import_jsx_runtime17 = require("react/jsx-runtime");
2179
2212
  function Panel(_a) {
2180
2213
  var _b = _a, { title, description, children, className } = _b, props = __objRest(_b, ["title", "description", "children", "className"]);
2181
2214
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", __spreadProps(__spreadValues({ className: cn("ph-panel", className) }, props), { children: [
2182
- title && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "text-sm font-semibold uppercase tracking-wider text-ph-mutedtext", children: title }),
2215
+ title && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "text-lg font-semibold tracking-tight text-ph-ink", children: title }),
2183
2216
  description && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm text-ph-subtle", children: description }),
2184
2217
  children
2185
2218
  ] }));
@@ -2251,21 +2284,41 @@ function Table({
2251
2284
  getRowStyle,
2252
2285
  getRowKey,
2253
2286
  className,
2254
- caption
2287
+ tableClassName,
2288
+ variant = "default",
2289
+ caption,
2290
+ emptyState = "No data available."
2255
2291
  }) {
2256
2292
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2257
2293
  "div",
2258
2294
  {
2259
- className: cn("ph-table-wrap", compact && "ph-table-compact", className),
2295
+ className: cn(
2296
+ variant === "report" ? "ph-table-report-wrap" : "ph-table-wrap",
2297
+ compact && "ph-table-compact",
2298
+ className
2299
+ ),
2300
+ role: "region",
2301
+ "aria-label": caption != null ? caption : "Data table",
2260
2302
  tabIndex: 0,
2261
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("table", { className: cn("ph-table", zebra && "ph-table-zebra", ribbon && "ph-table--ribbon"), children: [
2262
- caption && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("caption", { className: "sr-only", children: caption }),
2263
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tr", { children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("th", { className: col.className, children: col.header }, col.key)) }) }),
2264
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tbody", { children: data.map((row, i) => {
2265
- var _a;
2266
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tr", { style: getRowStyle == null ? void 0 : getRowStyle(row), children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("td", { className: col.className, children: col.cell(row) }, col.key)) }, (_a = getRowKey == null ? void 0 : getRowKey(row, i)) != null ? _a : i);
2267
- }) })
2268
- ] })
2303
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2304
+ "table",
2305
+ {
2306
+ className: cn(
2307
+ variant === "report" ? "ph-table-report" : "ph-table",
2308
+ zebra && "ph-table-zebra",
2309
+ ribbon && "ph-table--ribbon",
2310
+ tableClassName
2311
+ ),
2312
+ children: [
2313
+ caption && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("caption", { className: "sr-only", children: caption }),
2314
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tr", { children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("th", { scope: "col", className: col.className, children: col.header }, col.key)) }) }),
2315
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tbody", { children: data.length === 0 ? emptyState === null ? null : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("td", { colSpan: columns.length, className: "ph-table-empty", children: emptyState }) }) : data.map((row, i) => {
2316
+ var _a;
2317
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tr", { style: getRowStyle == null ? void 0 : getRowStyle(row), children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("td", { className: col.className, children: col.cell(row) }, col.key)) }, (_a = getRowKey == null ? void 0 : getRowKey(row, i)) != null ? _a : i);
2318
+ }) })
2319
+ ]
2320
+ }
2321
+ )
2269
2322
  }
2270
2323
  );
2271
2324
  }
@@ -2512,14 +2565,11 @@ function Accordion({
2512
2565
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2513
2566
  "div",
2514
2567
  {
2515
- className: cn(
2516
- "divide-y divide-ph-border rounded-xl border border-ph-border bg-ph-surface",
2517
- className
2518
- ),
2568
+ className: cn("ph-accordion", className),
2519
2569
  children: items.map((item) => {
2520
2570
  const isOpen = openItems.has(item.id);
2521
2571
  const contentId = `accordion-${idPrefix}-${item.id}-content`;
2522
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "first:rounded-t-xl last:rounded-b-xl", children: [
2572
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ph-accordion__item", children: [
2523
2573
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2524
2574
  "button",
2525
2575
  {
@@ -2527,7 +2577,7 @@ function Accordion({
2527
2577
  onClick: () => toggleItem(item.id),
2528
2578
  "aria-expanded": isOpen,
2529
2579
  "aria-controls": contentId,
2530
- className: "flex w-full items-center justify-between px-5 py-4 text-left transition hover:bg-ph-muted",
2580
+ className: "ph-accordion__trigger",
2531
2581
  children: [
2532
2582
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "font-semibold text-ph-ink", children: item.title }),
2533
2583
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
@@ -2551,7 +2601,7 @@ function Accordion({
2551
2601
  if (node) node.toggleAttribute("inert", !isOpen);
2552
2602
  },
2553
2603
  className: cn(
2554
- "grid transition-all duration-200",
2604
+ "grid transition-[grid-template-rows] duration-200",
2555
2605
  isOpen ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
2556
2606
  ),
2557
2607
  children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "px-5 pb-4 text-ph-subtle", children: item.content }) })
@@ -2564,27 +2614,68 @@ function Accordion({
2564
2614
  }
2565
2615
 
2566
2616
  // src/components/ui/SegmentedControl.tsx
2617
+ var import_react16 = require("react");
2567
2618
  var import_jsx_runtime23 = require("react/jsx-runtime");
2568
- function SegmentedControl({ options, value, onChange, className }) {
2619
+ function SegmentedControl({
2620
+ options,
2621
+ value,
2622
+ onChange,
2623
+ className,
2624
+ "aria-label": ariaLabel
2625
+ }) {
2626
+ const itemRefs = (0, import_react16.useRef)([]);
2627
+ const selectedIndex = options.findIndex((option) => option.value === value);
2628
+ const handleKeyDown = (event, index) => {
2629
+ var _a;
2630
+ let nextIndex;
2631
+ switch (event.key) {
2632
+ case "ArrowLeft":
2633
+ case "ArrowUp":
2634
+ nextIndex = (index - 1 + options.length) % options.length;
2635
+ break;
2636
+ case "ArrowRight":
2637
+ case "ArrowDown":
2638
+ nextIndex = (index + 1) % options.length;
2639
+ break;
2640
+ case "Home":
2641
+ nextIndex = 0;
2642
+ break;
2643
+ case "End":
2644
+ nextIndex = options.length - 1;
2645
+ break;
2646
+ default:
2647
+ return;
2648
+ }
2649
+ event.preventDefault();
2650
+ const nextOption = options[nextIndex];
2651
+ if (!nextOption) return;
2652
+ onChange(nextOption.value);
2653
+ (_a = itemRefs.current[nextIndex]) == null ? void 0 : _a.focus();
2654
+ };
2569
2655
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2570
2656
  "div",
2571
2657
  {
2572
- className: cn(
2573
- "inline-flex rounded-lg bg-ph-muted p-1",
2574
- className
2575
- ),
2576
- children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2658
+ role: "radiogroup",
2659
+ "aria-label": ariaLabel,
2660
+ className: cn("ph-segmented-control", className),
2661
+ children: options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2577
2662
  "button",
2578
2663
  {
2664
+ ref: (node) => {
2665
+ itemRefs.current[index] = node;
2666
+ },
2579
2667
  type: "button",
2580
- "aria-pressed": value === option.value,
2668
+ role: "radio",
2669
+ "aria-checked": value === option.value,
2670
+ tabIndex: selectedIndex === index || selectedIndex < 0 && index === 0 ? 0 : -1,
2581
2671
  onClick: () => onChange(option.value),
2672
+ onKeyDown: (event) => handleKeyDown(event, index),
2582
2673
  className: cn(
2583
- "relative flex min-h-11 items-center gap-1.5 rounded-md px-3.5 py-1.5 text-sm font-medium transition-all sm:min-h-9",
2584
- value === option.value ? "bg-ph-surface text-ph-ink shadow-ph" : "text-ph-subtle hover:text-ph-ink"
2674
+ "ph-segmented-control__item",
2675
+ value === option.value && "ph-segmented-control__item--selected"
2585
2676
  ),
2586
2677
  children: [
2587
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "h-4 w-4", children: option.icon }),
2678
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "h-4 w-4", "aria-hidden": true, children: option.icon }),
2588
2679
  option.label
2589
2680
  ]
2590
2681
  },
@@ -2595,7 +2686,7 @@ function SegmentedControl({ options, value, onChange, className }) {
2595
2686
  }
2596
2687
 
2597
2688
  // src/components/ui/CommandPalette.tsx
2598
- var import_react16 = require("react");
2689
+ var import_react17 = require("react");
2599
2690
  var Dialog2 = __toESM(require("@radix-ui/react-dialog"));
2600
2691
  var import_jsx_runtime24 = require("react/jsx-runtime");
2601
2692
  function CommandPalette({
@@ -2609,27 +2700,27 @@ function CommandPalette({
2609
2700
  inputId,
2610
2701
  inputDataTest
2611
2702
  }) {
2612
- const [query, setQuery] = (0, import_react16.useState)("");
2613
- const [selectedIndex, setSelectedIndex] = (0, import_react16.useState)(0);
2614
- const inputRef = (0, import_react16.useRef)(null);
2615
- const listboxRef = (0, import_react16.useRef)(null);
2616
- const restoreFocusRef = (0, import_react16.useRef)(null);
2617
- const generatedId = (0, import_react16.useId)();
2703
+ const [query, setQuery] = (0, import_react17.useState)("");
2704
+ const [selectedIndex, setSelectedIndex] = (0, import_react17.useState)(0);
2705
+ const inputRef = (0, import_react17.useRef)(null);
2706
+ const listboxRef = (0, import_react17.useRef)(null);
2707
+ const restoreFocusRef = (0, import_react17.useRef)(null);
2708
+ const generatedId = (0, import_react17.useId)();
2618
2709
  const listboxId = `${id != null ? id : `command-palette-${generatedId}`}-listbox`;
2619
2710
  const filtered = items.filter(
2620
2711
  (item) => item.label.toLowerCase().includes(query.toLowerCase())
2621
2712
  );
2622
2713
  const activeIndex = filtered.length ? Math.min(selectedIndex, filtered.length - 1) : 0;
2623
2714
  const activeItem = filtered[activeIndex];
2624
- (0, import_react16.useEffect)(() => {
2715
+ (0, import_react17.useEffect)(() => {
2625
2716
  if (!isOpen) return;
2626
2717
  setQuery("");
2627
2718
  setSelectedIndex(0);
2628
2719
  }, [isOpen]);
2629
- (0, import_react16.useEffect)(() => {
2720
+ (0, import_react17.useEffect)(() => {
2630
2721
  setSelectedIndex((current) => Math.min(current, Math.max(filtered.length - 1, 0)));
2631
2722
  }, [filtered.length]);
2632
- (0, import_react16.useEffect)(() => {
2723
+ (0, import_react17.useEffect)(() => {
2633
2724
  var _a, _b;
2634
2725
  if (!isOpen || !activeItem) return;
2635
2726
  (_b = (_a = listboxRef.current) == null ? void 0 : _a.querySelectorAll('[role="option"]')[activeIndex]) == null ? void 0 : _b.scrollIntoView({ block: "nearest" });
@@ -2671,16 +2762,13 @@ function CommandPalette({
2671
2762
  {
2672
2763
  id,
2673
2764
  "data-test": dataTest,
2674
- className: "fixed inset-0 z-50 bg-black/40 backdrop-blur-sm"
2765
+ className: "ph-command-palette__overlay"
2675
2766
  }
2676
2767
  ),
2677
2768
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2678
2769
  Dialog2.Content,
2679
2770
  {
2680
- className: cn(
2681
- "fixed left-1/2 top-[20vh] z-50 w-full max-w-xl -translate-x-1/2 overflow-hidden rounded-xl border border-ph-border bg-ph-surface shadow-ph-md",
2682
- className
2683
- ),
2771
+ className: cn("ph-command-palette", className),
2684
2772
  onOpenAutoFocus: (event) => {
2685
2773
  var _a;
2686
2774
  restoreFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
@@ -2694,7 +2782,7 @@ function CommandPalette({
2694
2782
  },
2695
2783
  children: [
2696
2784
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Dialog2.Title, { className: "sr-only", children: "Command palette" }),
2697
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-3 border-b border-ph-border px-4 py-3", children: [
2785
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "ph-command-palette__search", children: [
2698
2786
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconSearch, { className: "h-5 w-5 text-ph-mutedtext" }),
2699
2787
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2700
2788
  "input",
@@ -2719,7 +2807,7 @@ function CommandPalette({
2719
2807
  className: "flex-1 bg-transparent text-ph-ink outline-none placeholder:text-ph-mutedtext"
2720
2808
  }
2721
2809
  ),
2722
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { "aria-hidden": "true", className: "rounded border border-ph-border bg-ph-muted px-1.5 py-0.5 text-xs text-ph-mutedtext", children: "ESC" })
2810
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { "aria-hidden": "true", className: "ph-keycap", children: "ESC" })
2723
2811
  ] }),
2724
2812
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: listboxRef, id: listboxId, role: "listbox", "aria-label": "Commands", className: "max-h-[50vh] overflow-y-auto py-2", children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { role: "status", className: "px-4 py-8 text-center text-sm text-ph-mutedtext", children: "No results found." }) : filtered.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2725
2813
  "div",
@@ -2734,13 +2822,13 @@ function CommandPalette({
2734
2822
  },
2735
2823
  onMouseEnter: () => setSelectedIndex(index),
2736
2824
  className: cn(
2737
- "flex w-full cursor-pointer items-center gap-3 px-4 py-2.5 text-left text-sm transition-colors",
2738
- index === activeIndex ? "bg-ph-muted text-ph-ink" : "text-ph-subtle"
2825
+ "ph-command-palette__option",
2826
+ index === activeIndex ? "ph-command-palette__option--selected" : "text-ph-subtle"
2739
2827
  ),
2740
2828
  children: [
2741
2829
  item.icon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { "aria-hidden": "true", className: "h-5 w-5", children: item.icon }),
2742
2830
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "flex-1", children: item.label }),
2743
- item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { "aria-hidden": "true", className: "rounded border border-ph-border bg-ph-surface px-1.5 py-0.5 text-xs text-ph-mutedtext", children: item.shortcut })
2831
+ item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { "aria-hidden": "true", className: "ph-keycap text-ph-mutedtext", children: item.shortcut })
2744
2832
  ]
2745
2833
  },
2746
2834
  item.id
@@ -2754,7 +2842,7 @@ function CommandPalette({
2754
2842
  }
2755
2843
 
2756
2844
  // src/components/ui/Calendar.tsx
2757
- var import_react17 = require("react");
2845
+ var import_react18 = require("react");
2758
2846
  var import_jsx_runtime25 = require("react/jsx-runtime");
2759
2847
  var monthNames = [
2760
2848
  "January",
@@ -2812,19 +2900,19 @@ function dateLabel(date) {
2812
2900
  return `${fullWeekDays[date.getDay()]}, ${date.getDate()} ${monthNames[date.getMonth()]} ${date.getFullYear()}`;
2813
2901
  }
2814
2902
  function Calendar({ value, onChange, className }) {
2815
- const [currentMonth, setCurrentMonth] = (0, import_react17.useState)(() => startOfMonth(value != null ? value : /* @__PURE__ */ new Date()));
2816
- const [focusedDate, setFocusedDate] = (0, import_react17.useState)(() => startOfDay(value != null ? value : /* @__PURE__ */ new Date()));
2817
- const gridRef = (0, import_react17.useRef)(null);
2818
- const shouldFocusDateRef = (0, import_react17.useRef)(false);
2819
- const monthLabelId = (0, import_react17.useId)();
2903
+ const [currentMonth, setCurrentMonth] = (0, import_react18.useState)(() => startOfMonth(value != null ? value : /* @__PURE__ */ new Date()));
2904
+ const [focusedDate, setFocusedDate] = (0, import_react18.useState)(() => startOfDay(value != null ? value : /* @__PURE__ */ new Date()));
2905
+ const gridRef = (0, import_react18.useRef)(null);
2906
+ const shouldFocusDateRef = (0, import_react18.useRef)(false);
2907
+ const monthLabelId = (0, import_react18.useId)();
2820
2908
  const today = startOfDay(/* @__PURE__ */ new Date());
2821
- (0, import_react17.useEffect)(() => {
2909
+ (0, import_react18.useEffect)(() => {
2822
2910
  if (!value) return;
2823
2911
  const nextDate = startOfDay(value);
2824
2912
  setCurrentMonth(startOfMonth(nextDate));
2825
2913
  setFocusedDate(nextDate);
2826
2914
  }, [value]);
2827
- (0, import_react17.useEffect)(() => {
2915
+ (0, import_react18.useEffect)(() => {
2828
2916
  var _a, _b;
2829
2917
  if (!shouldFocusDateRef.current) return;
2830
2918
  (_b = (_a = gridRef.current) == null ? void 0 : _a.querySelector(`[data-date="${dateKey(focusedDate)}"]`)) == null ? void 0 : _b.focus();
@@ -2893,7 +2981,7 @@ function Calendar({ value, onChange, className }) {
2893
2981
  while (days.length < 42) {
2894
2982
  days.push(null);
2895
2983
  }
2896
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("w-[280px] rounded-xl border border-ph-border bg-ph-surface p-4 shadow-ph", className), children: [
2984
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("ph-calendar w-[280px] p-4", className), children: [
2897
2985
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "mb-4 flex items-center justify-between", children: [
2898
2986
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2899
2987
  "button",
@@ -2901,7 +2989,7 @@ function Calendar({ value, onChange, className }) {
2901
2989
  type: "button",
2902
2990
  onClick: () => changeMonth(-1),
2903
2991
  "aria-label": "Previous month",
2904
- className: "rounded-lg p-1 text-ph-subtle transition hover:bg-ph-muted hover:text-ph-ink",
2992
+ className: "ph-calendar__nav",
2905
2993
  children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IconChevronLeft, { className: "h-5 w-5", "aria-hidden": true })
2906
2994
  }
2907
2995
  ),
@@ -2916,7 +3004,7 @@ function Calendar({ value, onChange, className }) {
2916
3004
  type: "button",
2917
3005
  onClick: () => changeMonth(1),
2918
3006
  "aria-label": "Next month",
2919
- className: "rounded-lg p-1 text-ph-subtle transition hover:bg-ph-muted hover:text-ph-ink",
3007
+ className: "ph-calendar__nav",
2920
3008
  children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IconChevronRight, { className: "h-5 w-5", "aria-hidden": true })
2921
3009
  }
2922
3010
  )
@@ -2953,8 +3041,8 @@ function Calendar({ value, onChange, className }) {
2953
3041
  onClick: () => handleSelect(date),
2954
3042
  onKeyDown: (event) => handleDayKeyDown(event, date),
2955
3043
  className: cn(
2956
- "flex h-full w-full items-center justify-center rounded-lg text-sm transition-colors",
2957
- value && isSameDay(value, date) ? "bg-ph-brand font-semibold text-[var(--ph-on-accent)] shadow-ph" : isSameDay(today, date) ? "bg-ph-muted font-semibold text-ph-brand ring-1 ring-ph-brand/30" : "text-ph-ink hover:bg-ph-muted"
3044
+ "ph-calendar__day",
3045
+ value && isSameDay(value, date) ? "ph-calendar__day--selected" : isSameDay(today, date) ? "ph-calendar__day--today" : void 0
2958
3046
  ),
2959
3047
  children: date.getDate()
2960
3048
  }
@@ -2969,10 +3057,10 @@ function Calendar({ value, onChange, className }) {
2969
3057
  }
2970
3058
 
2971
3059
  // src/components/ui/Tooltip.tsx
2972
- var import_react18 = require("react");
3060
+ var import_react19 = require("react");
2973
3061
  var import_react_dom = require("react-dom");
2974
3062
  var import_jsx_runtime26 = require("react/jsx-runtime");
2975
- var TooltipDelayContext = (0, import_react18.createContext)(0);
3063
+ var TooltipDelayContext = (0, import_react19.createContext)(0);
2976
3064
  function TooltipProvider({
2977
3065
  children,
2978
3066
  delayDuration = 0
@@ -3004,13 +3092,13 @@ function Tooltip({
3004
3092
  delayDuration,
3005
3093
  disableHoverableContent = false
3006
3094
  }) {
3007
- const providerDelay = (0, import_react18.useContext)(TooltipDelayContext);
3008
- const generatedId = (0, import_react18.useId)().replace(/:/g, "");
3009
- const triggerRef = (0, import_react18.useRef)(null);
3010
- const contentRef = (0, import_react18.useRef)(null);
3011
- const timerRef = (0, import_react18.useRef)(null);
3012
- const [internalOpen, setInternalOpen] = (0, import_react18.useState)(defaultOpen);
3013
- const [position, setPosition] = (0, import_react18.useState)(null);
3095
+ const providerDelay = (0, import_react19.useContext)(TooltipDelayContext);
3096
+ const generatedId = (0, import_react19.useId)().replace(/:/g, "");
3097
+ const triggerRef = (0, import_react19.useRef)(null);
3098
+ const contentRef = (0, import_react19.useRef)(null);
3099
+ const timerRef = (0, import_react19.useRef)(null);
3100
+ const [internalOpen, setInternalOpen] = (0, import_react19.useState)(defaultOpen);
3101
+ const [position, setPosition] = (0, import_react19.useState)(null);
3014
3102
  const isOpen = open != null ? open : internalOpen;
3015
3103
  const triggerId = children.props.id;
3016
3104
  const tooltipId = triggerId ? `${triggerId}-tooltip` : `ph-tooltip-${generatedId}`;
@@ -3022,7 +3110,7 @@ function Tooltip({
3022
3110
  if (timerRef.current) clearTimeout(timerRef.current);
3023
3111
  timerRef.current = null;
3024
3112
  }
3025
- const updatePosition = (0, import_react18.useCallback)(() => {
3113
+ const updatePosition = (0, import_react19.useCallback)(() => {
3026
3114
  if (!triggerRef.current || !contentRef.current) return;
3027
3115
  setPosition(
3028
3116
  tooltipPosition(
@@ -3054,10 +3142,10 @@ function Tooltip({
3054
3142
  clearTimer();
3055
3143
  timerRef.current = setTimeout(() => setOpen(false), 100);
3056
3144
  }
3057
- (0, import_react18.useLayoutEffect)(() => {
3145
+ (0, import_react19.useLayoutEffect)(() => {
3058
3146
  if (isOpen) updatePosition();
3059
3147
  }, [isOpen, updatePosition]);
3060
- (0, import_react18.useEffect)(() => {
3148
+ (0, import_react19.useEffect)(() => {
3061
3149
  if (!isOpen) return;
3062
3150
  const reposition = () => updatePosition();
3063
3151
  window.addEventListener("resize", reposition);
@@ -3067,9 +3155,9 @@ function Tooltip({
3067
3155
  window.removeEventListener("scroll", reposition, true);
3068
3156
  };
3069
3157
  }, [isOpen, updatePosition]);
3070
- (0, import_react18.useEffect)(() => () => clearTimer(), []);
3158
+ (0, import_react19.useEffect)(() => () => clearTimer(), []);
3071
3159
  const describedBy = [children.props["aria-describedby"], tooltipId].filter(Boolean).join(" ");
3072
- const trigger = (0, import_react18.cloneElement)(children, { "aria-describedby": describedBy });
3160
+ const trigger = (0, import_react19.cloneElement)(children, { "aria-describedby": describedBy });
3073
3161
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
3074
3162
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3075
3163
  "span",
@@ -3123,11 +3211,11 @@ function EmptyState({ icon, title, description, action, className }) {
3123
3211
  "div",
3124
3212
  {
3125
3213
  className: cn(
3126
- "flex flex-col items-center justify-center rounded-xl border border-dashed border-ph-border bg-ph-muted/50 px-8 py-16 text-center",
3214
+ "ph-empty-state",
3127
3215
  className
3128
3216
  ),
3129
3217
  children: [
3130
- icon && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-ph-muted text-ph-mutedtext", children: icon }),
3218
+ icon && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "ph-empty-state__icon", children: icon }),
3131
3219
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { className: "text-base font-semibold text-ph-ink", children: title }),
3132
3220
  description && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "mt-1 max-w-sm text-sm text-ph-subtle", children: description }),
3133
3221
  action && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mt-4", children: action })
@@ -3304,7 +3392,7 @@ function getOptionText(option) {
3304
3392
  }
3305
3393
 
3306
3394
  // src/components/ui/Typography.tsx
3307
- var import_react19 = require("react");
3395
+ var import_react20 = require("react");
3308
3396
  var import_jsx_runtime30 = require("react/jsx-runtime");
3309
3397
  var toneMap2 = {
3310
3398
  default: "text-ph-ink",
@@ -3327,64 +3415,65 @@ var weightMap = {
3327
3415
  function textClass(base, tone, weight, truncate, className) {
3328
3416
  return cn(base, toneMap2[tone], weight && weightMap[weight], truncate && "truncate", className);
3329
3417
  }
3330
- var Display = (0, import_react19.forwardRef)(function Display2(_a, ref) {
3418
+ var Display = (0, import_react20.forwardRef)(function Display2(_a, ref) {
3331
3419
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3332
3420
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h1", __spreadProps(__spreadValues({ ref }, props), { className: textClass("ph-hero-title", tone, weight, truncate, className), children }));
3333
3421
  });
3334
- var SectionTitle = (0, import_react19.forwardRef)(function SectionTitle2(_a, ref) {
3422
+ var SectionTitle = (0, import_react20.forwardRef)(function SectionTitle2(_a, ref) {
3335
3423
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3336
3424
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h2", __spreadProps(__spreadValues({ ref }, props), { className: textClass("ph-section-title", tone, weight, truncate, className), children }));
3337
3425
  });
3338
- var H1 = (0, import_react19.forwardRef)(function H12(_a, ref) {
3426
+ var H1 = (0, import_react20.forwardRef)(function H12(_a, ref) {
3339
3427
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3340
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h1", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-3xl font-bold tracking-tight md:text-4xl", tone, weight, truncate, className), children }));
3428
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h1", __spreadProps(__spreadValues({ ref }, props), { className: textClass("ph-page-title font-bold", tone, weight, truncate, className), children }));
3341
3429
  });
3342
- var H2 = (0, import_react19.forwardRef)(function H22(_a, ref) {
3430
+ var H2 = (0, import_react20.forwardRef)(function H22(_a, ref) {
3343
3431
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3344
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h2", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-2xl font-bold tracking-tight", tone, weight, truncate, className), children }));
3432
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h2", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-2xl font-semibold tracking-tight", tone, weight, truncate, className), children }));
3345
3433
  });
3346
- var H3 = (0, import_react19.forwardRef)(function H32(_a, ref) {
3434
+ var H3 = (0, import_react20.forwardRef)(function H32(_a, ref) {
3347
3435
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3348
3436
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h3", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-xl font-semibold", tone, weight, truncate, className), children }));
3349
3437
  });
3350
- var H4 = (0, import_react19.forwardRef)(function H42(_a, ref) {
3438
+ var H4 = (0, import_react20.forwardRef)(function H42(_a, ref) {
3351
3439
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3352
3440
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h4", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-lg font-semibold", tone, weight, truncate, className), children }));
3353
3441
  });
3354
- var H5 = (0, import_react19.forwardRef)(function H52(_a, ref) {
3442
+ var H5 = (0, import_react20.forwardRef)(function H52(_a, ref) {
3355
3443
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3356
3444
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h5", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-base font-semibold", tone, weight, truncate, className), children }));
3357
3445
  });
3358
- var P = (0, import_react19.forwardRef)(function P2(_a, ref) {
3446
+ var P = (0, import_react20.forwardRef)(function P2(_a, ref) {
3359
3447
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3360
3448
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-base leading-relaxed", tone, weight, truncate, className), children }));
3361
3449
  });
3362
- var Small = (0, import_react19.forwardRef)(function Small2(_a, ref) {
3450
+ var Small = (0, import_react20.forwardRef)(function Small2(_a, ref) {
3363
3451
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3364
3452
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-sm leading-relaxed", tone, weight, truncate, className), children }));
3365
3453
  });
3366
- var Caption = (0, import_react19.forwardRef)(function Caption2(_a, ref) {
3454
+ var Caption = (0, import_react20.forwardRef)(function Caption2(_a, ref) {
3367
3455
  var _b = _a, { children, tone = "muted", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3368
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-[11px] font-medium uppercase tracking-wider", tone, weight, truncate, className), children }));
3456
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-xs font-medium", tone, weight, truncate, className), children }));
3369
3457
  });
3370
- var Overline = (0, import_react19.forwardRef)(function Overline2(_a, ref) {
3458
+ var Overline = (0, import_react20.forwardRef)(function Overline2(_a, ref) {
3371
3459
  var _b = _a, { children, tone = "muted", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3372
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-[10px] font-bold uppercase tracking-[0.15em]", tone, weight, truncate, className), children }));
3460
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-[length:var(--ph-type-overline)] font-semibold uppercase tracking-[0.08em]", tone, weight, truncate, className), children }));
3373
3461
  });
3374
- var Lead = (0, import_react19.forwardRef)(function Lead2(_a, ref) {
3462
+ var Lead = (0, import_react20.forwardRef)(function Lead2(_a, ref) {
3375
3463
  var _b = _a, { children, tone = "subtle", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3376
3464
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", __spreadProps(__spreadValues({ ref }, props), { className: textClass("ph-lead", tone, weight, truncate, className), children }));
3377
3465
  });
3378
- var Mono = (0, import_react19.forwardRef)(function Mono2(_a, ref) {
3466
+ var Mono = (0, import_react20.forwardRef)(function Mono2(_a, ref) {
3379
3467
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3380
3468
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("code", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-sm font-mono leading-relaxed", tone, weight, truncate, className), children }));
3381
3469
  });
3382
- var Label = (0, import_react19.forwardRef)(function Label2(_a, ref) {
3470
+ var Label = (0, import_react20.forwardRef)(function Label2(_a, ref) {
3383
3471
  var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
3384
3472
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-sm font-medium", tone, weight, truncate, className), children }));
3385
3473
  });
3386
3474
 
3387
3475
  // src/components/ui/Avatar.tsx
3476
+ var import_react21 = require("react");
3388
3477
  var import_jsx_runtime31 = require("react/jsx-runtime");
3389
3478
  var sizeMap4 = {
3390
3479
  xs: "h-8 w-8 text-[10px]",
@@ -3404,7 +3493,7 @@ function Avatar(_a) {
3404
3493
  label,
3405
3494
  icon,
3406
3495
  size = "md",
3407
- color = "bg-ph-brand text-white",
3496
+ color = "bg-ph-brand text-[var(--ph-on-accent)]",
3408
3497
  status,
3409
3498
  badge,
3410
3499
  className
@@ -3422,7 +3511,7 @@ function Avatar(_a) {
3422
3511
  "div",
3423
3512
  {
3424
3513
  className: cn(
3425
- "flex items-center justify-center rounded-full border border-ph-border font-bold shadow-ph",
3514
+ "ph-avatar flex items-center justify-center rounded-full border border-ph-border font-bold",
3426
3515
  sizeMap4[size],
3427
3516
  color
3428
3517
  ),
@@ -3440,12 +3529,12 @@ function Avatar(_a) {
3440
3529
  )
3441
3530
  }
3442
3531
  ),
3443
- badge && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "absolute -bottom-1 -right-1 flex min-w-[22px] items-center justify-center rounded-full bg-ph-brand px-1.5 py-px text-[10px] font-bold text-white", children: badge })
3532
+ badge && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "absolute -bottom-1 -right-1 flex min-w-[22px] items-center justify-center rounded-full bg-ph-brand px-1.5 py-px text-[10px] font-bold text-[var(--ph-on-accent)]", children: badge })
3444
3533
  ] }));
3445
3534
  }
3446
3535
  function AvatarGroup(_a) {
3447
3536
  var _b = _a, { children, max, className } = _b, props = __objRest(_b, ["children", "max", "className"]);
3448
- const items = Array.isArray(children) ? children : [children];
3537
+ const items = import_react21.Children.toArray(children);
3449
3538
  const visible = max ? items.slice(0, max) : items;
3450
3539
  const remaining = max ? items.length - max : 0;
3451
3540
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", __spreadProps(__spreadValues({ className: cn("-space-x-3 flex rtl:space-x-reverse", className) }, props), { children: [
@@ -3462,7 +3551,7 @@ function AvatarGroup(_a) {
3462
3551
  }
3463
3552
 
3464
3553
  // src/components/ui/Progress.tsx
3465
- var import_react20 = require("react");
3554
+ var import_react22 = require("react");
3466
3555
  var import_jsx_runtime32 = require("react/jsx-runtime");
3467
3556
  var sizeMap5 = {
3468
3557
  sm: "h-1",
@@ -3491,7 +3580,7 @@ function Progress(_a) {
3491
3580
  "aria-label",
3492
3581
  "aria-labelledby"
3493
3582
  ]);
3494
- const labelId = (0, import_react20.useId)();
3583
+ const labelId = (0, import_react22.useId)();
3495
3584
  const safeMax = Number.isFinite(max) && max > 0 ? max : 100;
3496
3585
  const safeValue = Number.isFinite(value) ? Math.min(safeMax, Math.max(0, value)) : 0;
3497
3586
  const percentage = safeValue / safeMax * 100;
@@ -3520,9 +3609,9 @@ function Progress(_a) {
3520
3609
  }
3521
3610
 
3522
3611
  // src/components/ui/Link.tsx
3523
- var import_react21 = require("react");
3612
+ var import_react23 = require("react");
3524
3613
  var import_jsx_runtime33 = require("react/jsx-runtime");
3525
- var Link = (0, import_react21.forwardRef)(function Link2(_a, ref) {
3614
+ var Link = (0, import_react23.forwardRef)(function Link2(_a, ref) {
3526
3615
  var _b = _a, {
3527
3616
  className,
3528
3617
  disabled = false,
@@ -3575,8 +3664,286 @@ function Spinner(_a) {
3575
3664
  }
3576
3665
  Spinner.displayName = "Spinner";
3577
3666
 
3578
- // src/components/ui/Dot.tsx
3667
+ // src/components/ui/BrandSpinner.tsx
3668
+ var import_react24 = require("react");
3579
3669
  var import_jsx_runtime35 = require("react/jsx-runtime");
3670
+ var sizes = { sm: 20, md: 40, lg: 56 };
3671
+ var reducedMotionQuery = "(prefers-reduced-motion: reduce)";
3672
+ function subscribeMotion(onChange) {
3673
+ var _a;
3674
+ const media = (_a = window.matchMedia) == null ? void 0 : _a.call(window, reducedMotionQuery);
3675
+ media == null ? void 0 : media.addEventListener("change", onChange);
3676
+ return () => media == null ? void 0 : media.removeEventListener("change", onChange);
3677
+ }
3678
+ function readReducedMotion() {
3679
+ var _a, _b;
3680
+ return (_b = (_a = window.matchMedia) == null ? void 0 : _a.call(window, reducedMotionQuery).matches) != null ? _b : false;
3681
+ }
3682
+ function BrandSpinner(_a) {
3683
+ var _b = _a, {
3684
+ variant = "ring",
3685
+ size = "md",
3686
+ label = "Loading",
3687
+ className
3688
+ } = _b, props = __objRest(_b, [
3689
+ "variant",
3690
+ "size",
3691
+ "label",
3692
+ "className"
3693
+ ]);
3694
+ const gradientId = `ph-spinner-${(0, import_react24.useId)().replace(/:/g, "")}`;
3695
+ const reducedMotion = (0, import_react24.useSyncExternalStore)(
3696
+ subscribeMotion,
3697
+ readReducedMotion,
3698
+ () => true
3699
+ );
3700
+ const dimension = sizes[size];
3701
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3702
+ "div",
3703
+ __spreadProps(__spreadValues({
3704
+ role: "status",
3705
+ "aria-label": label,
3706
+ "data-test": "app-spinner",
3707
+ className: cn(
3708
+ "inline-flex shrink-0",
3709
+ variant !== "orbit" && "text-ph-brand",
3710
+ className
3711
+ )
3712
+ }, props), {
3713
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3714
+ "svg",
3715
+ {
3716
+ width: dimension,
3717
+ height: dimension,
3718
+ viewBox: variant === "ring" ? "0 0 24 24" : "0 0 40 40",
3719
+ "aria-hidden": true,
3720
+ className: variant === "timer" || variant === "ring" ? "animate-spin motion-reduce:animate-none" : void 0,
3721
+ children: variant === "ring" ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
3722
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3723
+ "circle",
3724
+ {
3725
+ cx: "12",
3726
+ cy: "12",
3727
+ r: "10",
3728
+ fill: "none",
3729
+ stroke: "currentColor",
3730
+ strokeWidth: "3",
3731
+ opacity: "0.2"
3732
+ }
3733
+ ),
3734
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3735
+ "path",
3736
+ {
3737
+ d: "M12 2a10 10 0 0 1 10 10",
3738
+ fill: "none",
3739
+ stroke: "currentColor",
3740
+ strokeWidth: "3",
3741
+ strokeLinecap: "round"
3742
+ }
3743
+ )
3744
+ ] }) : variant === "timer" ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
3745
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3746
+ "circle",
3747
+ {
3748
+ cx: "20",
3749
+ cy: "20",
3750
+ r: "15",
3751
+ fill: "none",
3752
+ stroke: "currentColor",
3753
+ strokeOpacity: "0.18",
3754
+ strokeWidth: "2.5"
3755
+ }
3756
+ ),
3757
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3758
+ "circle",
3759
+ {
3760
+ cx: "20",
3761
+ cy: "20",
3762
+ r: "15",
3763
+ fill: "none",
3764
+ stroke: "currentColor",
3765
+ strokeWidth: "2.5",
3766
+ strokeLinecap: "round",
3767
+ strokeDasharray: "24 70"
3768
+ }
3769
+ ),
3770
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("circle", { cx: "20", cy: "5", r: "2.25", fill: "currentColor" })
3771
+ ] }) : variant === "columns" ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
3772
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3773
+ "rect",
3774
+ {
3775
+ x: "9",
3776
+ y: "16",
3777
+ width: "6",
3778
+ height: "14",
3779
+ rx: "2",
3780
+ fill: "currentColor",
3781
+ fillOpacity: "0.35",
3782
+ className: "ph-brand-spinner__column"
3783
+ }
3784
+ ),
3785
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3786
+ "rect",
3787
+ {
3788
+ x: "17",
3789
+ y: "11",
3790
+ width: "6",
3791
+ height: "19",
3792
+ rx: "2",
3793
+ fill: "currentColor",
3794
+ className: "ph-brand-spinner__column",
3795
+ style: { animationDelay: "0.14s" }
3796
+ }
3797
+ ),
3798
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3799
+ "rect",
3800
+ {
3801
+ x: "25",
3802
+ y: "14",
3803
+ width: "6",
3804
+ height: "16",
3805
+ rx: "2",
3806
+ fill: "currentColor",
3807
+ fillOpacity: "0.55",
3808
+ className: "ph-brand-spinner__column",
3809
+ style: { animationDelay: "0.28s" }
3810
+ }
3811
+ )
3812
+ ] }) : variant === "orbit" ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
3813
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
3814
+ "linearGradient",
3815
+ {
3816
+ id: gradientId,
3817
+ x1: "0%",
3818
+ y1: "0%",
3819
+ x2: "100%",
3820
+ y2: "100%",
3821
+ children: [
3822
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("stop", { offset: "0%", stopColor: "#1877f2" }),
3823
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("stop", { offset: "100%", stopColor: "#ebbcba" })
3824
+ ]
3825
+ }
3826
+ ) }),
3827
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3828
+ "circle",
3829
+ {
3830
+ cx: "20",
3831
+ cy: "20",
3832
+ r: "15",
3833
+ fill: "none",
3834
+ stroke: `url(#${gradientId})`,
3835
+ strokeOpacity: "0.25",
3836
+ strokeWidth: "2"
3837
+ }
3838
+ ),
3839
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("g", { className: "origin-[20px_20px] animate-spin motion-reduce:animate-none", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3840
+ "circle",
3841
+ {
3842
+ cx: "20",
3843
+ cy: "20",
3844
+ r: "15",
3845
+ fill: "none",
3846
+ stroke: `url(#${gradientId})`,
3847
+ strokeWidth: "2.5",
3848
+ strokeLinecap: "round",
3849
+ strokeDasharray: "22 72"
3850
+ }
3851
+ ) }),
3852
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("g", { className: "origin-[20px_20px] animate-[spin_1.6s_linear_infinite_reverse] motion-reduce:animate-none", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3853
+ "circle",
3854
+ {
3855
+ cx: "20",
3856
+ cy: "20",
3857
+ r: "9",
3858
+ fill: "none",
3859
+ stroke: "#ebbcba",
3860
+ strokeWidth: "2",
3861
+ strokeLinecap: "round",
3862
+ strokeDasharray: "12 45",
3863
+ strokeOpacity: "0.9"
3864
+ }
3865
+ ) }),
3866
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3867
+ "circle",
3868
+ {
3869
+ cx: "20",
3870
+ cy: "20",
3871
+ r: "2.5",
3872
+ fill: "#1877f2",
3873
+ className: "animate-pulse motion-reduce:animate-none"
3874
+ }
3875
+ )
3876
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
3877
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("g", { children: [
3878
+ !reducedMotion ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3879
+ "animateTransform",
3880
+ {
3881
+ attributeName: "transform",
3882
+ type: "rotate",
3883
+ from: "0 20 20",
3884
+ to: "360 20 20",
3885
+ dur: "2.4s",
3886
+ repeatCount: "indefinite"
3887
+ }
3888
+ ) : null,
3889
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3890
+ "circle",
3891
+ {
3892
+ cx: "20",
3893
+ cy: "20",
3894
+ r: "16",
3895
+ fill: "none",
3896
+ stroke: "currentColor",
3897
+ strokeOpacity: "0.2",
3898
+ strokeWidth: "1.5",
3899
+ strokeDasharray: "3 5"
3900
+ }
3901
+ )
3902
+ ] }),
3903
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("g", { children: [
3904
+ !reducedMotion ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3905
+ "animateTransform",
3906
+ {
3907
+ attributeName: "transform",
3908
+ type: "rotate",
3909
+ from: "360 20 20",
3910
+ to: "0 20 20",
3911
+ dur: "1.1s",
3912
+ repeatCount: "indefinite"
3913
+ }
3914
+ ) : null,
3915
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3916
+ "circle",
3917
+ {
3918
+ cx: "20",
3919
+ cy: "20",
3920
+ r: "11",
3921
+ fill: "none",
3922
+ stroke: "currentColor",
3923
+ strokeWidth: "2",
3924
+ strokeLinecap: "round",
3925
+ strokeDasharray: "18 52"
3926
+ }
3927
+ )
3928
+ ] }),
3929
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3930
+ "path",
3931
+ {
3932
+ d: "M16 14h8v12a1 1 0 0 1-1.4.9L20 25.5l-2.6 1.4A1 1 0 0 1 16 26V14z",
3933
+ fill: "currentColor",
3934
+ fillOpacity: "0.85",
3935
+ className: "animate-pulse motion-reduce:animate-none"
3936
+ }
3937
+ )
3938
+ ] })
3939
+ }
3940
+ )
3941
+ })
3942
+ );
3943
+ }
3944
+
3945
+ // src/components/ui/Dot.tsx
3946
+ var import_jsx_runtime36 = require("react/jsx-runtime");
3580
3947
  var colorMap = {
3581
3948
  green: "bg-ph-success",
3582
3949
  yellow: "bg-ph-warning",
@@ -3586,7 +3953,7 @@ var colorMap = {
3586
3953
  };
3587
3954
  function Dot(_a) {
3588
3955
  var _b = _a, { color = "gray", size = "md", className } = _b, props = __objRest(_b, ["color", "size", "className"]);
3589
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
3956
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
3590
3957
  "span",
3591
3958
  __spreadValues({
3592
3959
  className: cn(
@@ -3602,9 +3969,9 @@ function Dot(_a) {
3602
3969
  Dot.displayName = "Dot";
3603
3970
 
3604
3971
  // src/components/ui/Chip.tsx
3605
- var import_react22 = require("react");
3606
- var import_jsx_runtime36 = require("react/jsx-runtime");
3607
- var Chip = (0, import_react22.forwardRef)(function Chip2(_a, ref) {
3972
+ var import_react25 = require("react");
3973
+ var import_jsx_runtime37 = require("react/jsx-runtime");
3974
+ var Chip = (0, import_react25.forwardRef)(function Chip2(_a, ref) {
3608
3975
  var _b = _a, {
3609
3976
  selected = false,
3610
3977
  onRemove,
@@ -3623,18 +3990,18 @@ var Chip = (0, import_react22.forwardRef)(function Chip2(_a, ref) {
3623
3990
  );
3624
3991
  if (onRemove) {
3625
3992
  const removeLabel = typeof children === "string" ? `Remove ${children}` : "Remove";
3626
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: chipClassName, children: [
3627
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
3993
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: chipClassName, children: [
3994
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3628
3995
  "button",
3629
3996
  __spreadProps(__spreadValues({
3630
3997
  ref,
3631
3998
  type: "button",
3632
3999
  className: "min-w-0 bg-transparent p-0 text-inherit"
3633
4000
  }, props), {
3634
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ph-chip__text", children })
4001
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "ph-chip__text", children })
3635
4002
  })
3636
4003
  ),
3637
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4004
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3638
4005
  "button",
3639
4006
  {
3640
4007
  type: "button",
@@ -3642,19 +4009,19 @@ var Chip = (0, import_react22.forwardRef)(function Chip2(_a, ref) {
3642
4009
  disabled: props.disabled,
3643
4010
  className: "ph-chip__remove",
3644
4011
  "aria-label": removeLabel,
3645
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("path", { d: "M2 2l6 6M8 2l-6 6" }) })
4012
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("path", { d: "M2 2l6 6M8 2l-6 6" }) })
3646
4013
  }
3647
4014
  )
3648
4015
  ] });
3649
4016
  }
3650
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4017
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3651
4018
  "button",
3652
4019
  __spreadProps(__spreadValues({
3653
4020
  ref,
3654
4021
  type: "button",
3655
4022
  className: chipClassName
3656
4023
  }, props), {
3657
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ph-chip__text", children })
4024
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "ph-chip__text", children })
3658
4025
  })
3659
4026
  );
3660
4027
  });
@@ -3669,6 +4036,7 @@ Chip.displayName = "Chip";
3669
4036
  Avatar,
3670
4037
  AvatarGroup,
3671
4038
  Badge,
4039
+ BrandSpinner,
3672
4040
  Button,
3673
4041
  ButtonChrome,
3674
4042
  CANONICAL_ICONS,
@@ -3793,6 +4161,7 @@ Chip.displayName = "Chip";
3793
4161
  Panel,
3794
4162
  Progress,
3795
4163
  Radio,
4164
+ SUITE_ANALYTICS_EVENT,
3796
4165
  SearchInput,
3797
4166
  SectionTitle,
3798
4167
  SegmentedControl,
@@ -3819,5 +4188,7 @@ Chip.displayName = "Chip";
3819
4188
  getTheme,
3820
4189
  isThemeId,
3821
4190
  persistTheme,
3822
- readStoredTheme
4191
+ readStoredTheme,
4192
+ subscribeSuiteAnalytics,
4193
+ trackSuiteEvent
3823
4194
  });