@exxatdesignux/ui 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/dist/components/data-table/filter-text-value-input.js +1 -1
  3. package/dist/components/data-table/filter-text-value-input.js.map +1 -1
  4. package/dist/components/data-table/index.js +3 -3
  5. package/dist/components/data-table/index.js.map +1 -1
  6. package/dist/components/data-table/pagination.js +3 -3
  7. package/dist/components/data-table/pagination.js.map +1 -1
  8. package/dist/components/data-views/data-row-list.js +1 -1
  9. package/dist/components/data-views/data-row-list.js.map +1 -1
  10. package/dist/components/data-views/hub-table.js +6 -6
  11. package/dist/components/data-views/hub-table.js.map +1 -1
  12. package/dist/components/data-views/index.js +6 -6
  13. package/dist/components/data-views/index.js.map +1 -1
  14. package/dist/components/table-properties/column-row.js +1 -1
  15. package/dist/components/table-properties/column-row.js.map +1 -1
  16. package/dist/components/table-properties/drawer-button.js +5 -5
  17. package/dist/components/table-properties/drawer-button.js.map +1 -1
  18. package/dist/components/table-properties/drawer.js +5 -5
  19. package/dist/components/table-properties/drawer.js.map +1 -1
  20. package/dist/components/table-properties/filter-card.js +2 -2
  21. package/dist/components/table-properties/filter-card.js.map +1 -1
  22. package/dist/components/table-properties/index.js +5 -5
  23. package/dist/components/table-properties/index.js.map +1 -1
  24. package/dist/components/table-properties/sort-card.js +1 -1
  25. package/dist/components/table-properties/sort-card.js.map +1 -1
  26. package/dist/components/templates/index.js +4 -4
  27. package/dist/components/templates/index.js.map +1 -1
  28. package/dist/components/templates/list-page.js +4 -4
  29. package/dist/components/templates/list-page.js.map +1 -1
  30. package/dist/components/ui/banner.js +1 -1
  31. package/dist/components/ui/banner.js.map +1 -1
  32. package/dist/components/ui/coach-mark.js +1 -1
  33. package/dist/components/ui/coach-mark.js.map +1 -1
  34. package/dist/components/ui/context-menu.js +1 -1
  35. package/dist/components/ui/context-menu.js.map +1 -1
  36. package/dist/components/ui/date-picker-field.js +1 -1
  37. package/dist/components/ui/date-picker-field.js.map +1 -1
  38. package/dist/components/ui/dropdown-menu.js +2 -2
  39. package/dist/components/ui/dropdown-menu.js.map +1 -1
  40. package/dist/components/ui/export-drawer.js +3 -3
  41. package/dist/components/ui/export-drawer.js.map +1 -1
  42. package/dist/components/ui/hover-card.js +1 -1
  43. package/dist/components/ui/hover-card.js.map +1 -1
  44. package/dist/components/ui/key-metrics.js +6 -6
  45. package/dist/components/ui/key-metrics.js.map +1 -1
  46. package/dist/components/ui/page-header.js +1 -1
  47. package/dist/components/ui/page-header.js.map +1 -1
  48. package/dist/components/ui/popover.js +1 -1
  49. package/dist/components/ui/popover.js.map +1 -1
  50. package/dist/components/ui/select.js +1 -1
  51. package/dist/components/ui/select.js.map +1 -1
  52. package/dist/components/ui/sheet.js +1 -1
  53. package/dist/components/ui/sheet.js.map +1 -1
  54. package/dist/components/ui/sidebar.d.ts +1 -1
  55. package/dist/components/ui/sidebar.js +3 -3
  56. package/dist/components/ui/sidebar.js.map +1 -1
  57. package/dist/components/ui/tip.js +1 -1
  58. package/dist/components/ui/tip.js.map +1 -1
  59. package/dist/components/ui/tooltip.js +1 -1
  60. package/dist/components/ui/tooltip.js.map +1 -1
  61. package/dist/components/ui/view-segmented-control.js +1 -1
  62. package/dist/components/ui/view-segmented-control.js.map +1 -1
  63. package/dist/index.js +16 -16
  64. package/dist/index.js.map +1 -1
  65. package/package.json +1 -1
  66. package/src/components/data-views/data-row-list.tsx +1 -1
  67. package/src/components/ui/banner.tsx +0 -2
  68. package/src/components/ui/coach-mark.tsx +1 -2
  69. package/src/components/ui/context-menu.tsx +1 -1
  70. package/src/components/ui/dropdown-menu.tsx +2 -2
  71. package/src/components/ui/hover-card.tsx +1 -1
  72. package/src/components/ui/key-metrics.tsx +4 -4
  73. package/src/components/ui/popover.tsx +1 -1
  74. package/src/components/ui/select.tsx +1 -1
  75. package/src/components/ui/sheet.tsx +1 -1
  76. package/src/components/ui/sidebar.tsx +3 -3
  77. package/src/components/ui/tooltip.tsx +1 -1
  78. package/template/package.json +10 -0
  79. package/tokens/hooks-index.json +2 -2
@@ -30,7 +30,7 @@ function HoverCardContent({
30
30
  align,
31
31
  sideOffset,
32
32
  className: cn(
33
- "z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-lg bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
33
+ "z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-lg bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
34
34
  className
35
35
  ),
36
36
  ...props
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/hover-card.tsx"],"names":["HoverCardPrimitive"],"mappings":";;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACwBA,SAAS,SAAA,CAAU;AAAA,EACjB,GAAG;AACL,CAAA,EAAyD;AACvD,EAAA,2BAAQA,WAAA,CAAmB,IAAA,EAAnB,EAAwB,WAAA,EAAU,YAAA,EAAc,GAAG,KAAA,EAAO,CAAA;AACpE;AAEA,SAAS,gBAAA,CAAiB;AAAA,EACxB,GAAG;AACL,CAAA,EAA4D;AAC1D,EAAA,2BACGA,WAAA,CAAmB,OAAA,EAAnB,EAA2B,WAAA,EAAU,oBAAA,EAAsB,GAAG,KAAA,EAAO,CAAA;AAE1E;AAEA,SAAS,gBAAA,CAAiB;AAAA,EACxB,SAAA;AAAA,EACA,KAAA,GAAQ,QAAA;AAAA,EACR,UAAA,GAAa,CAAA;AAAA,EACb,GAAG;AACL,CAAA,EAA4D;AAC1D,EAAA,uBACE,GAAA,CAACA,WAAA,CAAmB,MAAA,EAAnB,EAA0B,aAAU,mBAAA,EACnC,QAAA,kBAAA,GAAA;AAAA,IAACA,WAAA,CAAmB,OAAA;AAAA,IAAnB;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,KAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,4cAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN,EACF,CAAA;AAEJ","file":"hover-card.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\n/**\n * HoverCard — richer, persistent hover surface for content too large or\n * interactive for a `Tooltip` (avatars, link previews, user cards, glossary\n * entries).\n *\n * When to choose `HoverCard` vs `Tooltip` vs `Popover`:\n * - **`Tooltip`** — short text label, no interaction, auto-dismiss on\n * mouseout / blur. Pairs with `Tip` for icon-only buttons.\n * - **`HoverCard`** — small interactive content (links, copy buttons,\n * avatars) shown on intentional hover; closes when the pointer leaves.\n * Not focusable / not announced by screen readers — pair with an\n * accessible alternative for keyboard users (visit profile link, etc.).\n * - **`Popover`** — keyboard- and screen-reader-accessible, opens on\n * explicit click. Use this when the surface holds primary content.\n *\n * Accessibility (per Radix):\n * - HoverCard is NOT exposed to screen readers — Radix intentionally\n * treats it as a sighted-mouse-user affordance. The trigger MUST also\n * convey its meaning through its own accessible name and behaviour\n * (e.g. a focusable `<a>` that links to the same content).\n */\n\nimport * as React from \"react\"\nimport { HoverCard as HoverCardPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction HoverCard({\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />\n}\n\nfunction HoverCardTrigger({\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n return (\n <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n )\n}\n\nfunction HoverCardContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n return (\n <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n <HoverCardPrimitive.Content\n data-slot=\"hover-card-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-lg bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className,\n )}\n {...props}\n />\n </HoverCardPrimitive.Portal>\n )\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent }\n"]}
1
+ {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/hover-card.tsx"],"names":["HoverCardPrimitive"],"mappings":";;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACwBA,SAAS,SAAA,CAAU;AAAA,EACjB,GAAG;AACL,CAAA,EAAyD;AACvD,EAAA,2BAAQA,WAAA,CAAmB,IAAA,EAAnB,EAAwB,WAAA,EAAU,YAAA,EAAc,GAAG,KAAA,EAAO,CAAA;AACpE;AAEA,SAAS,gBAAA,CAAiB;AAAA,EACxB,GAAG;AACL,CAAA,EAA4D;AAC1D,EAAA,2BACGA,WAAA,CAAmB,OAAA,EAAnB,EAA2B,WAAA,EAAU,oBAAA,EAAsB,GAAG,KAAA,EAAO,CAAA;AAE1E;AAEA,SAAS,gBAAA,CAAiB;AAAA,EACxB,SAAA;AAAA,EACA,KAAA,GAAQ,QAAA;AAAA,EACR,UAAA,GAAa,CAAA;AAAA,EACb,GAAG;AACL,CAAA,EAA4D;AAC1D,EAAA,uBACE,GAAA,CAACA,WAAA,CAAmB,MAAA,EAAnB,EAA0B,aAAU,mBAAA,EACnC,QAAA,kBAAA,GAAA;AAAA,IAACA,WAAA,CAAmB,OAAA;AAAA,IAAnB;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,KAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,2cAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN,EACF,CAAA;AAEJ","file":"hover-card.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\n/**\n * HoverCard — richer, persistent hover surface for content too large or\n * interactive for a `Tooltip` (avatars, link previews, user cards, glossary\n * entries).\n *\n * When to choose `HoverCard` vs `Tooltip` vs `Popover`:\n * - **`Tooltip`** — short text label, no interaction, auto-dismiss on\n * mouseout / blur. Pairs with `Tip` for icon-only buttons.\n * - **`HoverCard`** — small interactive content (links, copy buttons,\n * avatars) shown on intentional hover; closes when the pointer leaves.\n * Not focusable / not announced by screen readers — pair with an\n * accessible alternative for keyboard users (visit profile link, etc.).\n * - **`Popover`** — keyboard- and screen-reader-accessible, opens on\n * explicit click. Use this when the surface holds primary content.\n *\n * Accessibility (per Radix):\n * - HoverCard is NOT exposed to screen readers — Radix intentionally\n * treats it as a sighted-mouse-user affordance. The trigger MUST also\n * convey its meaning through its own accessible name and behaviour\n * (e.g. a focusable `<a>` that links to the same content).\n */\n\nimport * as React from \"react\"\nimport { HoverCard as HoverCardPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction HoverCard({\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />\n}\n\nfunction HoverCardTrigger({\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n return (\n <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n )\n}\n\nfunction HoverCardContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n return (\n <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n <HoverCardPrimitive.Content\n data-slot=\"hover-card-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-lg bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className,\n )}\n {...props}\n />\n </HoverCardPrimitive.Portal>\n )\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent }\n"]}
@@ -118,7 +118,7 @@ function SelectContent({
118
118
  {
119
119
  "data-slot": "select-content",
120
120
  "data-align-trigger": position === "item-aligned",
121
- className: cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 rtl:data-[side=left]:translate-x-1 data-[side=right]:translate-x-1 rtl:data-[side=right]:-translate-x-1 data-[side=top]:-translate-y-1", className),
121
+ className: cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 rtl:data-[side=left]:translate-x-1 data-[side=right]:translate-x-1 rtl:data-[side=right]:-translate-x-1 data-[side=top]:-translate-y-1", className),
122
122
  position,
123
123
  align,
124
124
  ...props,
@@ -302,7 +302,7 @@ function TooltipContent({
302
302
  "data-slot": "tooltip-content",
303
303
  sideOffset,
304
304
  className: cn(
305
- "z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
305
+ "z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
306
306
  className
307
307
  ),
308
308
  ...props,
@@ -374,7 +374,7 @@ function flatMetricsHairlineClass(itemCount, metricsHalfWidthLayout) {
374
374
  if (itemCount <= 1) return "gap-0";
375
375
  const childBorder = "[&>*]:border-[color:var(--key-metrics-flat-divider)]";
376
376
  if (itemCount === 2) {
377
- return cn("gap-0", childBorder, "[&>*:first-child]:border-r");
377
+ return cn("gap-0", childBorder, "[&>*:first-child]:border-e");
378
378
  }
379
379
  if (itemCount === 4) {
380
380
  const narrow2x2 = metricsHalfWidthLayout ? "@[max-width:25.99rem]" : "@[max-width:29.99rem]";
@@ -382,14 +382,14 @@ function flatMetricsHairlineClass(itemCount, metricsHalfWidthLayout) {
382
382
  "gap-0",
383
383
  childBorder,
384
384
  /* Wide strip (matches `@[30rem]:grid-cols-4`) — verticals between all tiles, no horizontal */
385
- "[&>*:not(:last-child)]:border-r",
385
+ "[&>*:not(:last-child)]:border-e",
386
386
  /* Narrow strip (`@[18rem]`–`@[30rem]` 2×2) */
387
387
  `${narrow2x2}:[&>*:not(:last-child)]:border-e-0`,
388
- `${narrow2x2}:[&>*:nth-child(odd)]:border-r`,
388
+ `${narrow2x2}:[&>*:nth-child(odd)]:border-e`,
389
389
  `${narrow2x2}:[&>*:not(:nth-last-child(-n+2))]:border-b`
390
390
  );
391
391
  }
392
- return cn("gap-0", childBorder, "[&>*:not(:last-child)]:border-r");
392
+ return cn("gap-0", childBorder, "[&>*:not(:last-child)]:border-e");
393
393
  }
394
394
  function metricsRowColumnsClass(rowLength, metricsHalfWidthLayout) {
395
395
  const half = metricsHalfWidthLayout;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/card.tsx","../../../src/components/ui/select.tsx","../../../src/components/ui/separator.tsx","../../../src/components/ui/button.tsx","../../../src/components/ui/tooltip.tsx","../../../src/components/ui/key-metrics-context.tsx","../../../src/components/ui/key-metrics.tsx"],"names":["jsx","SelectPrimitive","SeparatorPrimitive","React","TooltipPrimitive","jsxs","memo","React3","MetricCell","Fragment"],"mappings":"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","file":"key-metrics.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","/**\n * Card — surface component\n *\n * ── SPACING SYSTEM (do not override) ────────────────────────────────────────\n * Card owns all vertical rhythm:\n * py-4 → 16px top + 16px bottom padding on the card itself\n * gap-4 → 16px gap between CardHeader, CardContent, and CardFooter\n *\n * Rules:\n * ✗ Never add pb-X / pt-X to CardContent or CardHeader\n * ✗ Never add h-full / flex / flex-col to the Card wrapper\n * ✗ Never add flex-1 / min-h-0 to CardContent\n * ✗ Never add shrink-0 / pb-2 to CardHeader\n * ✓ For scrollable list content (Activity, Tasks): add overflow-auto only\n * ✓ For equal-height grid pairs in MixView: handle at grid cell level\n *\n * ── GLOW TREATMENT ──────────────────────────────────────────────────────────\n * Only two approved uses — see full spec in key-metrics.tsx GLOW GUIDELINE:\n * 1. AI surfaces (Insights card, Ask Leo responses) → opacity 0.12–0.16\n * 2. Hero sections (Key Metrics KPI band, onboarding) → opacity 0.18–0.24\n * Always pair with overflow-hidden on the Card.\n * Never add glow to: Tasks, Activity, Learn, Charts, nav elements.\n *\n * ── FOOTER PATTERN ──────────────────────────────────────────────────────────\n * Use CardFooter for card-level CTA actions (e.g. \"View all tasks\", \"Ask Leo\").\n * CardFooter renders with border-t + bg-muted/50 automatically.\n * Do not put primary workflow actions in CardFooter — use CardHeader CardAction.\n *\n * ── SIZE VARIANT ────────────────────────────────────────────────────────────\n * size=\"sm\" → tighter spacing (py-3, gap-3, px-3). Use inside compact grids.\n * size=\"default\" (implicit) → standard spacing described above.\n */\n\nimport * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-slot=\"card\"\n data-size={size}\n className={cn(\n \"group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\n \"font-sans text-base leading-snug font-medium group-data-[size=sm]/card:text-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-4 group-data-[size=sm]/card:px-3\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n \"flex items-center rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/card:p-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Select({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return (\n <SelectPrimitive.Group\n data-slot=\"select-group\"\n className={cn(\"scroll-my-1 p-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectValue({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\"\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit cursor-pointer items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pe-2 ps-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/15 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <i className=\"fa-light fa-chevron-down pointer-events-none size-4 text-muted-foreground\" aria-hidden=\"true\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"item-aligned\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n data-align-trigger={position === \"item-aligned\"}\n className={cn(\"relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", position ===\"popper\"&&\"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 rtl:data-[side=left]:translate-x-1 data-[side=right]:translate-x-1 rtl:data-[side=right]:-translate-x-1 data-[side=top]:-translate-y-1\", className )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n data-position={position}\n className={cn(\n \"data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)\",\n position === \"popper\" && \"\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"px-1.5 py-1 text-xs text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pe-8 ps-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_i]:pointer-events-none [&_svg]:shrink-0 [&_i]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute end-2 flex size-4 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <i className=\"fa-light fa-check pointer-events-none\" aria-hidden=\"true\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <i className=\"fa-light fa-chevron-up\" aria-hidden=\"true\"\n />\n </SelectPrimitive.ScrollUpButton>\n )\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <i className=\"fa-light fa-chevron-down\" aria-hidden=\"true\"\n />\n </SelectPrimitive.ScrollDownButton>\n )\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Separator as SeparatorPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch\",\n className,\n )}\n {...props}\n />\n )\n}\n\nexport { Separator }\n","import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 cursor-pointer items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\n outline:\n \"border-input bg-background hover:bg-interactive-hover hover:text-interactive-hover-foreground aria-expanded:bg-interactive-hover aria-expanded:text-interactive-hover-foreground dark:bg-input/15 dark:hover:bg-input/25\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-interactive-hover hover:text-interactive-hover-foreground aria-expanded:bg-interactive-hover aria-expanded:text-interactive-hover-foreground dark:hover:bg-interactive-hover-subtle\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pe-2.5 has-data-[icon=inline-start]:ps-2.5\",\n xs: \"h-6 gap-1 px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-8 gap-1 px-3 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2 [&_svg:not([class*='size-'])]:size-3.5\",\n lg: \"h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pe-3.5 has-data-[icon=inline-start]:ps-3.5\",\n icon: \"size-9\",\n \"icon-xs\":\n \"size-6 in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-8 in-data-[slot=button-group]:rounded-lg\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nconst Button = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }\n>(({ className, variant = \"default\", size = \"default\", asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n ref={ref}\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n )\n})\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n}\n\nfunction TooltipTrigger({\n className,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return (\n <TooltipPrimitive.Trigger\n data-slot=\"tooltip-trigger\"\n suppressHydrationWarning\n className={cn(\"cursor-pointer\", className)}\n {...props}\n />\n )\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }\n","\"use client\"\n\n/**\n * KeyMetricsProvider — host-app injection point for the design-system\n * `KeyMetrics` component.\n *\n * `KeyMetrics` itself ships as a pure primitive: it knows how to render\n * a KPI strip, an insight rail, and a default insight CTA, but it does\n * NOT know anything about the host app's AI assistant, command palette,\n * or keyboard-shortcut registry.\n *\n * Consumers (e.g. `apps/web`) mount a `KeyMetricsProvider` near the root\n * of the app and supply two optional injection points:\n *\n * - `defaultInsightAction` — fired when the user clicks the default\n * \"Ask Leo about these metrics\" button in the card-variant header,\n * and the default insight CTA when an individual `MetricInsight` did\n * not supply its own `onAction`. When omitted, the default button is\n * hidden entirely so the primitive stays useful in apps without an\n * AI assistant.\n *\n * - `shortcutHint` — inline React node rendered inside the tooltip\n * alongside the action label (typically a keyboard chord such as\n * `<Kbd>⌘⌥K</Kbd>`). When omitted, the tooltip simply shows the\n * label.\n *\n * - `defaultActionLabel` — visible label + accessible name for the\n * default action button. Defaults to \"Ask Leo\" so the existing\n * Exxat-DS layout reads identically without any consumer changes.\n *\n * This is the SAME injection shape used by Adobe Spectrum\n * (`Provider`-based service injection) and Material UI (`Theme`\n * context). It lets the design-system package ship product patterns\n * without taking on a hard dependency on the host app's AI surface.\n */\n\nimport * as React from \"react\"\n\nexport interface KeyMetricsContextValue {\n /** Click handler for the default \"Ask Leo about these metrics\" CTA. */\n defaultInsightAction?: () => void\n /** Inline kbd chord (or any node) rendered next to the action label inside the tooltip. */\n shortcutHint?: React.ReactNode\n /** Label + aria-label for the default insight action button. Defaults to \"Ask Leo\". */\n defaultActionLabel?: string\n}\n\nconst KeyMetricsContext = React.createContext<KeyMetricsContextValue>({})\n\n/** Read the active `KeyMetricsProvider` value. Returns an empty object if no provider is mounted. */\nexport function useKeyMetricsContext(): KeyMetricsContextValue {\n return React.useContext(KeyMetricsContext)\n}\n\nexport function KeyMetricsProvider({\n value,\n children,\n}: {\n value: KeyMetricsContextValue\n children: React.ReactNode\n}) {\n // Memoize the wrapper so consumers passing fresh object identities\n // (common in client components) do not invalidate every descendant\n // that reads the context.\n const memo = React.useMemo<KeyMetricsContextValue>(\n () => ({\n defaultInsightAction: value.defaultInsightAction,\n shortcutHint: value.shortcutHint,\n defaultActionLabel: value.defaultActionLabel,\n }),\n [value.defaultInsightAction, value.shortcutHint, value.defaultActionLabel],\n )\n return (\n <KeyMetricsContext.Provider value={memo}>\n {children}\n </KeyMetricsContext.Provider>\n )\n}\n","\"use client\"\n\n/**\n * KeyMetrics — WCAG 2.1 AA reusable KPI panel\n *\n * Variants:\n * \"card\" (default) — shadcn Card wrapper with brand gradient fill\n * \"flat\" — full-width soft tint band (brand-tint → background) + bottom glow, no card chrome\n *\n * AA checklist:\n * ✓ Trend text never relies on colour alone — icon + label (WCAG 1.4.1)\n * ✓ `trend` matches signed change; `trendPolarity` flips sentiment when “up” is bad (see `docs/kpi-trend-pattern.md`)\n * ✓ Trend icons have aria-hidden; chip `aria-label` uses `metricTrendAriaQualifier` (1.1.1)\n * ✓ Select has accessible label via aria-label (4.1.2)\n * ✓ Insight action button has descriptive text (4.1.2)\n * ✓ Decorative dividers are aria-hidden (1.1.1)\n * ✓ Contrast: value text foreground ≥ 17:1, trend colours ≥ 4.5:1 (1.4.3)\n */\n\nimport * as React from \"react\"\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"./card\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"./select\"\nimport { Separator } from \"./separator\"\nimport { Button } from \"./button\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"./tooltip\"\nimport { cn } from \"../../lib/utils\"\nimport { useKeyMetricsContext } from \"./key-metrics-context\"\n\nexport {\n KeyMetricsProvider,\n useKeyMetricsContext,\n type KeyMetricsContextValue,\n} from \"./key-metrics-context\"\n\n/**\n * Tooltip around the default insight CTA. Renders the shortcut hint\n * injected by `KeyMetricsProvider` (typically `⌘⌥K` for Ask Leo) when\n * the CTA still uses the default action label — i.e. the consumer did\n * NOT override `actionLabel` on the individual `MetricInsight`. Any\n * custom `actionLabel` (\"Open ticket\", \"Acknowledge\", …) suppresses\n * the shortcut hint since it no longer maps to the default chord.\n */\nfunction InsightDefaultTooltip({\n actionLabel,\n children,\n}: {\n actionLabel?: string\n children: React.ReactNode\n}) {\n const { shortcutHint, defaultActionLabel = \"Ask Leo\" } = useKeyMetricsContext()\n const label = actionLabel ?? defaultActionLabel\n const showShortcut =\n !!shortcutHint && (!actionLabel || actionLabel === defaultActionLabel)\n if (!showShortcut) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>{children}</TooltipTrigger>\n <TooltipContent side=\"top\">{label}</TooltipContent>\n </Tooltip>\n )\n }\n return (\n <Tooltip>\n <TooltipTrigger asChild>{children}</TooltipTrigger>\n <TooltipContent side=\"top\" className=\"flex flex-wrap items-center gap-1.5\">\n <span>{label}</span>\n {shortcutHint}\n </TooltipContent>\n </Tooltip>\n )\n}\n\n/* ── Types ────────────────────────────────────────────────────────────────── */\n\n/**\n * Whether an **up** arrow should read as “good news” for tinting and assistive text.\n * - **`higher_is_better`** (default) — revenue, pass rate, approved count: up = favorable.\n * - **`lower_is_better`** — defects, overdue, **low PBI / quality flags**: more flags + up arrow = unfavorable.\n * - **`informational`** — volume or mix only; keep arrows **muted** (direction without value judgment).\n */\nexport type MetricTrendPolarity = \"higher_is_better\" | \"lower_is_better\" | \"informational\"\n\nexport type MetricTrendTone = \"positive\" | \"negative\" | \"muted\"\n\n/** Maps `trend` + polarity to semantic tone for colours (arrow direction still follows `trend`). */\nexport function metricTrendTone(\n trend: \"up\" | \"down\" | \"neutral\",\n polarity: MetricTrendPolarity = \"higher_is_better\",\n): MetricTrendTone {\n if (trend === \"neutral\") return \"muted\"\n if (polarity === \"informational\") return \"muted\"\n if (polarity === \"higher_is_better\") {\n return trend === \"up\" ? \"positive\" : \"negative\"\n }\n return trend === \"up\" ? \"negative\" : \"positive\"\n}\n\n/** Short clause for `aria-label` on the trend chip (paired with the delta string). */\nexport function metricTrendAriaQualifier(\n trend: \"up\" | \"down\" | \"neutral\",\n polarity: MetricTrendPolarity = \"higher_is_better\",\n): string {\n if (trend === \"neutral\") return \"no net change\"\n if (polarity === \"informational\") {\n return trend === \"up\" ? \"increased\" : \"decreased\"\n }\n if (polarity === \"higher_is_better\") {\n return trend === \"up\" ? \"increased, favorable\" : \"decreased, unfavorable\"\n }\n return trend === \"up\" ? \"increased, unfavorable\" : \"decreased, favorable\"\n}\n\nexport interface MetricItem {\n /** Unique identifier for React keying */\n id: string\n /** Short label shown above the value */\n label: string\n /** Displayed value — e.g. \"23\", \"98%\", \"1,250\" */\n value: string | number\n /**\n * Change **count** for the trend chip — e.g. `\"+5\"`, `\"-3\"`, `\"+12%\"`.\n *\n * Pass an **empty string** (or `0`) when there is no comparison delta to show.\n * In that case the **trend chip is hidden entirely** (the previous `—` placeholder\n * is dropped) — see `MetricCell`. Put contextual prose like\n * `\"left + right\"` / `\"vs last week\"` in `description`, **never** here.\n */\n delta: string | number\n /**\n * Visual trend direction (arrow follows the signed change in the underlying metric).\n * `\"neutral\"` paired with an empty `delta` suppresses the chip — use `description`\n * for any caption you want to show below the value instead.\n */\n trend: \"up\" | \"down\" | \"neutral\"\n /**\n * Optional short caption rendered **below** the value + trend row (muted, small).\n * Use for **what** the number means or **how** it breaks down\n * (e.g. `\"left + right\"`, `\"vs last week\"`, `\"across 4 sites\"`) — NOT for delta counts.\n */\n description?: string\n /**\n * How to **tint** the trend chip. Omit = **`higher_is_better`** (legacy behaviour).\n * Arrows always match `trend`; sentiment colours flip for **`lower_is_better`**.\n */\n trendPolarity?: MetricTrendPolarity\n /** Makes the cell a link */\n href?: string\n /** Makes the cell a button */\n onClick?: () => void\n /**\n * \"hero\" — primary KPI (e.g. total count): larger value, same structure as siblings.\n * \"default\" — standard KPI strip cell.\n */\n metricVariant?: \"default\" | \"hero\"\n}\n\nexport interface MetricInsight {\n /** Optional single line for custom copy; rail prefers `title` + `description` when both are set */\n statement?: string\n /** Card headline */\n title: string\n /** Supporting body copy */\n description?: string\n /** Optional deep-link for the ↗ button */\n href?: string\n /** CTA label — defaults to \"Ask Leo\" */\n actionLabel?: string\n /** Font Awesome class for the CTA icon — defaults to fa-wand-magic-sparkles */\n actionIcon?: string\n /** Callback for the CTA button */\n onAction?: () => void\n /** Severity determines the badge colour (default: warning) */\n severity?: \"warning\" | \"info\" | \"error\"\n}\n\nexport interface PeriodOption {\n value: string\n label: string\n}\n\nexport interface KeyMetricsProps {\n /**\n * \"card\" — shadcn Card with brand gradient (default)\n * \"flat\" — full-width gradient band, no card chrome\n */\n variant?: \"card\" | \"flat\" | \"compact\"\n /** Panel title */\n title?: string\n /** Subtitle / description below title */\n description?: string\n /** Array of KPI items — by default split into rows of 3 */\n metrics: MetricItem[]\n /** When true, all metrics share one horizontal row (md+ and compact mobile grid) */\n metricsSingleRow?: boolean\n /**\n * When true with `metricsSingleRow`, use a 2-column KPI grid so half-width dashboard cards\n * fit 1–4 KPIs without horizontal overflow (pair rows on md+; 2-col grid on small screens).\n * The insight rail (if any) stacks below the KPI grid instead of sitting beside it on md+.\n */\n metricsHalfWidthLayout?: boolean\n /** Optional insight card — see `insightFullWidth` */\n insight?: MetricInsight\n /**\n * When true, the insight sits on its own full-width row under the metrics (not a narrow side rail).\n */\n insightFullWidth?: boolean\n /** Comparison-period options for the Select */\n periods?: PeriodOption[]\n /** Initially-selected period value */\n defaultPeriod?: string\n /** Called with the new period value when the Select changes */\n onPeriodChange?: (period: string) => void\n /** When false, hides the title/description/period-selector header row (default: true) */\n showHeader?: boolean\n /**\n * Tighter insight card: one short title + line of body, no vertical filler;\n * aligns visually with a single-row KPI band.\n */\n insightCompact?: boolean\n className?: string\n}\n\n/**\n * KPI grid column step patterns — Tailwind v4 container-query classes.\n *\n * We deliberately AVOID `repeat(auto-fit, minmax(...))` here because it\n * produces awkward \"N + leftover\" layouts at intermediate widths (e.g. 3\n * tiles in row 1 + 1 lonely tile in row 2 for a 4-KPI strip). Instead we\n * step the column count through values that evenly divide the row size:\n * 1 → 2 → 4 for a 4-KPI strip (3 is skipped on purpose).\n *\n * The breakpoints are container-query based (`@[Xrem]:…`) so they react to\n * the metrics strip's OWN width, not the viewport — that's what makes the\n * 2×2 fallback kick in when the primary sidebar + secondary panel are\n * both open and the strip column is ~360 px wide, even on a 1280 px display.\n *\n * `metricsHalfWidthLayout` = strip shares its row with the insight rail\n * (3fr / 2fr split). Tighter breakpoints because available width is ~60%\n * of the section.\n */\n/**\n * Flat KPI hairlines — cell borders only (no grid gap fill / no surface).\n * Four tiles: default 4-across verticals; 2×2 hairlines only when @container is narrow.\n */\nfunction flatMetricsHairlineClass(\n itemCount: number,\n metricsHalfWidthLayout: boolean,\n): string {\n if (itemCount <= 1) return \"gap-0\"\n\n const childBorder = \"[&>*]:border-[color:var(--key-metrics-flat-divider)]\"\n\n if (itemCount === 2) {\n return cn(\"gap-0\", childBorder, \"[&>*:first-child]:border-r\")\n }\n\n if (itemCount === 4) {\n const narrow2x2 = metricsHalfWidthLayout\n ? \"@[max-width:25.99rem]\"\n : \"@[max-width:29.99rem]\"\n return cn(\n \"gap-0\",\n childBorder,\n /* Wide strip (matches `@[30rem]:grid-cols-4`) — verticals between all tiles, no horizontal */\n \"[&>*:not(:last-child)]:border-r\",\n /* Narrow strip (`@[18rem]`–`@[30rem]` 2×2) */\n `${narrow2x2}:[&>*:not(:last-child)]:border-e-0`,\n `${narrow2x2}:[&>*:nth-child(odd)]:border-r`,\n `${narrow2x2}:[&>*:not(:nth-last-child(-n+2))]:border-b`,\n )\n }\n\n return cn(\"gap-0\", childBorder, \"[&>*:not(:last-child)]:border-r\")\n}\n\nfunction metricsRowColumnsClass(rowLength: number, metricsHalfWidthLayout: boolean): string {\n const half = metricsHalfWidthLayout\n switch (rowLength) {\n case 1:\n return \"grid-cols-1\"\n case 2:\n return half\n ? \"grid-cols-1 @[14rem]:grid-cols-2\"\n : \"grid-cols-1 @[18rem]:grid-cols-2\"\n case 3:\n // 3 tiles divide evenly already — step 1 → 3.\n return half\n ? \"grid-cols-1 @[18rem]:grid-cols-3\"\n : \"grid-cols-1 @[24rem]:grid-cols-3\"\n case 4:\n // Step 1 → 2 (2×2 grid) → 4. Skip 3 — that's the awkward 3+1 layout.\n // Aggressive 4-col thresholds so the strip fits all four tiles even\n // when the primary sidebar + secondary panel + insight rail are all\n // expanded (typical library layout puts the KPI grid at ~27rem).\n return half\n ? \"grid-cols-1 @[14rem]:grid-cols-2 @[26rem]:grid-cols-4\"\n : \"grid-cols-1 @[18rem]:grid-cols-2 @[30rem]:grid-cols-4\"\n default:\n // 5+ KPIs (`exxat-kpi-max-four` caps the strip at 4, but key-metrics\n // is a generic primitive — fall back to a sensible step). 1 → 2 → 3 → 6.\n return half\n ? \"grid-cols-1 @[14rem]:grid-cols-2 @[26rem]:grid-cols-3 @[40rem]:grid-cols-6\"\n : \"grid-cols-1 @[18rem]:grid-cols-2 @[30rem]:grid-cols-3 @[56rem]:grid-cols-6\"\n }\n}\n\n/* ── Default data ─────────────────────────────────────────────────────────── */\n\nconst DEFAULT_PERIODS: PeriodOption[] = [\n { value: \"week\", label: \"vs last week\" },\n { value: \"month\", label: \"vs last month\" },\n { value: \"quarter\", label: \"vs last quarter\" },\n { value: \"year\", label: \"vs last year\" },\n]\n\n/* ── Sub-components ───────────────────────────────────────────────────────── */\n\n/** Single KPI cell inside the metrics grid */\nconst MetricCell = React.memo(function MetricCell({\n label,\n value,\n delta,\n trend,\n trendPolarity = \"higher_is_better\",\n description,\n href,\n onClick,\n metricVariant = \"default\",\n dense = false,\n edgeGutter = true,\n}: Omit<MetricItem, \"id\"> & { dense?: boolean; edgeGutter?: boolean }) {\n const isUp = trend === \"up\"\n const isDown = trend === \"down\"\n const tone = metricTrendTone(trend, trendPolarity)\n const isInteractive = !!(href || onClick)\n const isHero = metricVariant === \"hero\"\n\n // Hide the trend chip entirely when there's no direction *and* no count to\n // surface. This avoids the noisy `—` placeholder for purely informational\n // metrics — see `docs/kpi-trend-pattern.md`.\n const deltaText = typeof delta === \"number\"\n ? (delta === 0 ? \"\" : String(delta))\n : String(delta ?? \"\").trim()\n const showTrendChip = isUp || isDown || deltaText.length > 0\n\n const inner = (\n <>\n {/* Label row — min-height = 2 lines so values align when some titles wrap */}\n <div\n className={cn(\n \"grid grid-cols-[minmax(0,1fr)_auto] items-start gap-x-2 gap-y-0.5\",\n dense ? \"min-h-[2.125rem]\" : \"min-h-[2.625rem]\",\n )}\n >\n <p\n className={cn(\n \"min-w-0 text-muted-foreground leading-snug wrap-break-word\",\n dense ? \"text-xs\" : \"text-sm\",\n isHero && \"font-medium\",\n )}\n >\n {label}\n </p>\n {isInteractive ? (\n <span className=\"mt-0.5 inline-flex shrink-0\" aria-hidden=\"true\">\n <i className=\"fa-light fa-arrow-right text-xs text-foreground/70 transition-colors duration-150 group-hover:text-interactive-hover-foreground sm:group-hover:translate-x-0.5\" />\n </span>\n ) : null}\n </div>\n\n {/* Value + trend badge */}\n <div className=\"flex items-baseline gap-2 flex-wrap\">\n <span\n className={cn(\n \"font-bold tabular-nums leading-none text-foreground\",\n dense\n ? isHero\n ? \"text-lg sm:text-xl\"\n : \"text-base sm:text-lg\"\n : isHero\n ? \"text-2xl sm:text-[1.625rem]\"\n : \"text-xl sm:text-2xl\",\n )}\n >\n {value}\n </span>\n\n {/* Trend chip — icon + count, never colour-only (WCAG 1.4.1).\n Suppressed when both `trend === \"neutral\"` and `delta` is empty\n (see `showTrendChip` above) so informational KPIs render cleanly. */}\n {showTrendChip && (\n <span\n className={cn(\n \"inline-flex items-center gap-1 font-medium leading-none\",\n dense ? \"text-xs sm:text-xs\" : \"text-xs sm:text-sm\",\n tone === \"positive\" && \"text-chart-2\",\n tone === \"negative\" && \"text-destructive\",\n tone === \"muted\" && \"text-muted-foreground\",\n )}\n aria-label={`${metricTrendAriaQualifier(trend, trendPolarity)} ${deltaText}`.trim()}\n >\n {isUp && <i className=\"fa-light fa-arrow-trend-up text-[0.8rem]\" aria-hidden=\"true\" />}\n {isDown && <i className=\"fa-light fa-arrow-trend-down text-[0.8rem]\" aria-hidden=\"true\" />}\n {!isUp && !isDown && deltaText.length > 0 && (\n <i className=\"fa-light fa-minus text-[0.8rem]\" aria-hidden=\"true\" />\n )}\n {deltaText.length > 0 && <span>{deltaText}</span>}\n </span>\n )}\n </div>\n\n {/* Caption — below the value row. Use for what the number means or how\n it breaks down (e.g. \"left + right\", \"vs last week\"). Never the delta. */}\n {description ? (\n <p\n className={cn(\n \"min-w-0 text-muted-foreground leading-snug wrap-break-word\",\n dense ? \"text-[11px]\" : \"text-xs\",\n )}\n >\n {description}\n </p>\n ) : null}\n </>\n )\n\n const sharedClass = cn(\n \"group flex min-w-0 flex-col gap-2 text-start outline-none\",\n edgeGutter && \"first:ps-0 last:pe-0\",\n dense ? \"gap-1.5 px-2 py-2 sm:px-3 sm:py-3\" : \"gap-2 px-3 py-3 sm:px-5 sm:py-4\",\n isHero && \"gap-2.5\",\n isInteractive && [\n \"cursor-pointer transition-colors duration-150\",\n \"hover:bg-foreground/5\",\n \"focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\",\n ]\n )\n\n if (href) {\n return (\n <a href={href} className={sharedClass} aria-label={`${label}: ${value}`}>\n {inner}\n </a>\n )\n }\n\n if (onClick) {\n return (\n <button type=\"button\" onClick={onClick} className={sharedClass} aria-label={`${label}: ${value}`}>\n {inner}\n </button>\n )\n }\n\n return <div className={sharedClass}>{inner}</div>\n})\n\n/** Body line for rail: `description`, else optional `statement` */\nfunction insightRailBody(insight: MetricInsight): string {\n const d = insight.description?.trim()\n if (d) return d\n return insight.statement?.trim() ?? \"\"\n}\n\n/**\n * Rail insight: severity badge + title + description + optional ↗, Ask Leo (no rule between copy and action).\n */\nfunction InsightRailStatementAction({\n insight,\n compact,\n}: {\n insight: MetricInsight\n compact: boolean\n}) {\n const badgeSize = compact ? \"sm\" : \"default\"\n const surface = compact\n ? \"border border-border/50 bg-gradient-to-b from-muted/35 to-card\"\n : \"bg-card\"\n const body = insightRailBody(insight)\n\n return (\n <Card\n role=\"region\"\n aria-label=\"Insight\"\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-hidden rounded-lg border-0 p-0 shadow-none ring-1 ring-foreground/8\",\n surface\n )}\n >\n {/* flex-1 + mt-auto on the CTA: copy stays top-aligned when the rail stretches to KPI height */}\n <div className=\"flex min-h-0 flex-1 flex-col px-3 py-3 sm:px-4 sm:py-4\">\n <div className=\"flex items-start gap-2.5\">\n <InsightBadge severity={insight.severity} size={badgeSize} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold leading-snug text-foreground\">{insight.title}</p>\n {body ? (\n <p className=\"mt-1 text-sm leading-snug text-muted-foreground\">{body}</p>\n ) : null}\n </div>\n {insight.href && (\n <a\n href={insight.href}\n className=\"mt-0.5 shrink-0 text-muted-foreground transition-colors hover:text-interactive-hover-foreground focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-ring\"\n aria-label={`Open ${insight.title} — details`}\n >\n <i className=\"fa-light fa-arrow-up-right text-xs\" aria-hidden=\"true\" />\n </a>\n )}\n </div>\n\n <div className=\"mt-auto flex shrink-0 justify-end pt-3\">\n <InsightDefaultTooltip actionLabel={insight.actionLabel}>\n <Button\n variant={compact ? \"outline\" : \"ghost\"}\n size=\"sm\"\n className={cn(\n \"h-8 w-full gap-1.5 text-xs sm:w-auto\",\n compact\n ? \"border-border/60 bg-background px-3 text-foreground hover:bg-background\"\n : \"px-3 text-muted-foreground hover:text-interactive-hover-foreground\"\n )}\n onClick={insight.onAction}\n aria-label={insight.actionLabel ?? \"Ask Leo\"}\n >\n <i\n className={\n insight.actionIcon\n ? `fa-light ${insight.actionIcon} text-xs`\n : \"fa-duotone fa-solid fa-star-christmas text-xs text-brand\"\n }\n aria-hidden=\"true\"\n />\n {insight.actionLabel ?? \"Ask Leo\"}\n </Button>\n </InsightDefaultTooltip>\n </div>\n </div>\n </Card>\n )\n}\n\n/** Severity icon badge for the insight card */\n\nfunction InsightBadge({\n severity = \"warning\",\n size = \"default\",\n}: {\n severity?: MetricInsight[\"severity\"]\n size?: \"default\" | \"sm\"\n}) {\n const styles = {\n warning: {\n bg: \"bg-[var(--insight-severity-warning-bg)]\",\n icon: \"fa-circle-exclamation\",\n color: \"text-[var(--insight-severity-warning-fg)]\",\n },\n info: {\n bg: \"bg-[var(--insight-severity-info-bg)]\",\n icon: \"fa-circle-info\",\n color: \"text-[var(--insight-severity-info-fg)]\",\n },\n error: { bg: \"bg-destructive/15\", icon: \"fa-circle-xmark\", color: \"text-destructive\" },\n }[severity]\n\n return (\n <span\n className={cn(\n \"inline-flex shrink-0 items-center justify-center rounded-full\",\n size === \"sm\" ? \"h-6 w-6 text-xs\" : \"h-7 w-7 text-sm\",\n styles.bg,\n styles.color\n )}\n aria-hidden=\"true\"\n >\n <i className={`fa-light ${styles.icon}`} />\n </span>\n )\n}\n\n/* ── Shared inner content ─────────────────────────────────────────────────── */\n\ninterface InnerProps {\n title: string\n description: string\n period: string\n periods: PeriodOption[]\n metrics: MetricItem[]\n rows: MetricItem[][]\n insight?: MetricInsight\n onPeriodChange: (v: string) => void\n /** Extra padding class injected by flat variant */\n innerPadding?: string\n /** When false, the header (title/description/period select) is hidden */\n showHeader?: boolean\n insightCompact?: boolean\n insightFullWidth?: boolean\n metricsSingleRow?: boolean\n /** Tighter KPI cells + 2-col mobile grid (half-width dashboard card). */\n metricsHalfWidthLayout?: boolean\n /** Opaque fill behind each KPI cell when using hairline grid gaps (below `lg`). */\n metricsCellSurfaceClassName?: string\n /** Flat list-page band: softer dividers + tinted cells on a lavender-tinted surface */\n surfaceVariant?: \"default\" | \"flat\"\n}\n\nfunction KeyMetricsInner({\n title,\n description,\n period,\n periods,\n metrics,\n rows,\n insight,\n onPeriodChange,\n innerPadding = \"\",\n showHeader = true,\n insightCompact = false,\n insightFullWidth = false,\n metricsSingleRow = false,\n metricsHalfWidthLayout = false,\n metricsCellSurfaceClassName = \"bg-background\",\n surfaceVariant = \"default\",\n}: InnerProps) {\n const isFlatBand = surfaceVariant === \"flat\"\n const metricsGridClassName = isFlatBand\n ? flatMetricsHairlineClass(metrics.length, metricsHalfWidthLayout)\n : \"gap-px bg-border\"\n /** Side-by-side KPI + insight rail (md+). Disabled for half-width dashboard cards — insight stacks below. */\n const insightSideBySide = insight && !insightFullWidth && !metricsHalfWidthLayout\n const stackedRailInsight = insight && !insightFullWidth && metricsHalfWidthLayout\n\n return (\n <div data-slot=\"key-metrics\" className=\"contents\">\n {/* ── Header ──────────────────────────────────────────────────── */}\n {showHeader && (\n <div className={cn(\n \"flex flex-col gap-2 pb-3\",\n \"sm:flex-row sm:items-center sm:justify-between sm:gap-4\",\n innerPadding\n )}>\n <div>\n <p className=\"text-base font-semibold text-foreground leading-tight\">{title}</p>\n <p className=\"mt-0.5 text-sm text-muted-foreground\">{description}</p>\n </div>\n\n {/* Period selector — align=\"end\" keeps dropdown flush-right */}\n <Select value={period} onValueChange={onPeriodChange}>\n <SelectTrigger\n className=\"h-8 w-full sm:w-auto sm:min-w-[9rem] shrink-0 text-sm\"\n aria-label=\"Select comparison period\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\" sideOffset={4}>\n {periods.map((p) => (\n <SelectItem key={p.value} value={p.value}>\n {p.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n\n {/* ── Body: metrics grid + optional insight ───────────────────── */}\n <div\n className={cn(\n \"flex flex-col gap-0\",\n /* 60% KPIs / 40% insight (3fr:2fr); lg+ only so phones/tablets stack KPIs + insight */\n insightSideBySide &&\n \"lg:grid lg:grid-cols-[minmax(0,3fr)_minmax(13rem,2fr)] lg:items-stretch lg:gap-x-6 lg:gap-y-0\",\n innerPadding\n )}\n >\n\n {/* Metrics section — self-start so KPI cells don’t stretch when the insight column is taller */}\n <div\n className={cn(\n \"min-w-0 lg:flex lg:min-h-0 lg:flex-col\",\n !insightSideBySide && \"w-full\",\n insightSideBySide && \"lg:self-start\"\n )}\n >\n {/*\n Phone (<md): one column. Tablet (md–lg): 2-column grid (e.g. 2×2 for four KPIs).\n Hairline separators use gap-px + opaque cell surfaces (divide-* breaks for 2-col order).\n Half-width dashboard cards keep divide-x + optional template columns.\n */}\n {metricsHalfWidthLayout ? (\n <div\n className={cn(\n \"@container/metrics-strip grid lg:hidden\",\n metricsSingleRow\n ? metricsRowColumnsClass(metrics.length, /* half */ true)\n : \"grid-cols-2\",\n metricsGridClassName,\n )}\n >\n {metrics.map((m) => (\n <div key={m.id} className={cn(\"min-w-0\", metricsCellSurfaceClassName)}>\n <MetricCell {...m} dense edgeGutter={false} />\n </div>\n ))}\n </div>\n ) : (\n <div\n className={cn(\n \"@container/metrics-strip grid lg:hidden\",\n metricsRowColumnsClass(metrics.length, /* half */ false),\n metricsGridClassName,\n )}\n >\n {metrics.map((m) => (\n <div key={m.id} className={cn(\"min-w-0\", metricsCellSurfaceClassName)}>\n <MetricCell {...m} dense={false} edgeGutter={false} />\n </div>\n ))}\n </div>\n )}\n\n {/*\n lg+: row-by-row container-queried grid. Uses a `gap-px + bg` hairline\n instead of `divide-x` so dividers render correctly when the row wraps\n from 4-across to a 2×2 grid (the awkward 3+1 layout is skipped — see\n `metricsRowColumnsClass`).\n */}\n <div className=\"@container/metrics-strip hidden lg:block\">\n {rows.map((row, rowIdx) => (\n <React.Fragment key={rowIdx}>\n {rowIdx > 0 && !isFlatBand && (\n <Separator aria-hidden=\"true\" className=\"my-1\" />\n )}\n <div\n className={cn(\n \"grid\",\n metricsRowColumnsClass(row.length, metricsHalfWidthLayout),\n isFlatBand\n ? flatMetricsHairlineClass(row.length, metricsHalfWidthLayout)\n : metricsGridClassName,\n )}\n >\n {row.map((m) => (\n <div key={m.id} className={cn(\"min-w-0\", metricsCellSurfaceClassName)}>\n <MetricCell {...m} dense={metricsHalfWidthLayout} edgeGutter={false} />\n </div>\n ))}\n </div>\n </React.Fragment>\n ))}\n </div>\n </div>\n\n {/* Insight card — only rendered when data provided */}\n {insight && (\n <>\n {insightFullWidth ? (\n <Separator\n aria-hidden=\"true\"\n className={cn(\"my-4 w-full\", isFlatBand && \"bg-foreground/[0.06]\")}\n />\n ) : stackedRailInsight ? (\n <Separator\n aria-hidden=\"true\"\n className={cn(\"my-4 w-full\", isFlatBand && \"bg-foreground/[0.06]\")}\n />\n ) : (\n <Separator\n aria-hidden=\"true\"\n className={cn(\"my-3 lg:hidden\", isFlatBand && \"bg-foreground/[0.055]\")}\n />\n )}\n\n <div\n className={cn(\n \"flex min-h-0 min-w-0 w-full flex-col\",\n /* Divider + padding replace vertical Separator so grid stays 2 columns */\n insightSideBySide &&\n !insightFullWidth &&\n cn(\n \"lg:h-full lg:ps-6\",\n /* Flat band: insight card ring is the divider — skip `border-l` (double line). */\n !isFlatBand && \"lg:border-s lg:border-border\",\n )\n )}\n >\n {insight && !insightFullWidth ? (\n <InsightRailStatementAction insight={insight} compact={insightCompact} />\n ) : (\n <Card\n role=\"region\"\n aria-label=\"Insight\"\n className={cn(\n \"overflow-hidden rounded-lg p-0 ring-1 ring-foreground/8 shadow-none\",\n \"flex min-h-0 flex-col bg-muted/25\"\n )}\n >\n {insightCompact ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-4 p-4 md:flex-row md:items-center md:justify-between md:gap-8 md:p-5\">\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n <div className=\"flex items-start gap-2.5\">\n <InsightBadge severity={insight.severity} size=\"sm\" />\n <div className=\"flex min-w-0 flex-1 items-start justify-between gap-2\">\n <p className=\"text-base font-semibold leading-tight text-foreground\">\n {insight.title}\n </p>\n {insight.href && (\n <a\n href={insight.href}\n className=\"shrink-0 text-muted-foreground transition-colors hover:text-interactive-hover-foreground focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-ring\"\n aria-label={`Open ${insight.title} — details`}\n >\n <i className=\"fa-light fa-arrow-up-right text-xs\" aria-hidden=\"true\" />\n </a>\n )}\n </div>\n </div>\n {insight.description ? (\n <p className=\"text-sm leading-relaxed text-muted-foreground\">\n {insight.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex w-full shrink-0 md:w-auto\">\n <InsightDefaultTooltip actionLabel={insight.actionLabel}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full gap-1.5 px-4 text-xs text-muted-foreground hover:text-interactive-hover-foreground md:min-w-[8.5rem]\"\n onClick={insight.onAction}\n aria-label={insight.actionLabel ?? \"Ask Leo\"}\n >\n <i\n className={insight.actionIcon ? `fa-light ${insight.actionIcon} text-xs` : \"fa-duotone fa-solid fa-star-christmas text-xs text-brand\"}\n aria-hidden=\"true\"\n />\n {insight.actionLabel ?? \"Ask Leo\"}\n </Button>\n </InsightDefaultTooltip>\n </div>\n </div>\n ) : (\n <div className=\"flex min-h-0 flex-1 flex-col gap-4 p-4 md:flex-row md:items-center md:justify-between md:gap-8 md:p-5\">\n <div className=\"flex min-w-0 flex-1 flex-col gap-3\">\n <div className=\"flex items-start gap-3\">\n <InsightBadge severity={insight.severity} />\n <div className=\"flex min-w-0 flex-1 items-start justify-between gap-2\">\n <p className=\"text-base font-semibold leading-snug text-foreground\">\n {insight.title}\n </p>\n {insight.href && (\n <a\n href={insight.href}\n className=\"shrink-0 text-muted-foreground transition-colors hover:text-interactive-hover-foreground focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-ring\"\n aria-label={`Open ${insight.title} — details`}\n >\n <i className=\"fa-light fa-arrow-up-right text-xs\" aria-hidden=\"true\" />\n </a>\n )}\n </div>\n </div>\n {insight.description ? (\n <p className=\"text-sm leading-relaxed text-muted-foreground\">\n {insight.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex w-full shrink-0 md:w-auto\">\n <InsightDefaultTooltip actionLabel={insight.actionLabel}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full gap-1.5 px-4 text-xs text-muted-foreground hover:text-interactive-hover-foreground md:min-w-[8.5rem]\"\n onClick={insight.onAction}\n aria-label={insight.actionLabel ?? \"Ask Leo\"}\n >\n <i\n className={insight.actionIcon ? `fa-light ${insight.actionIcon} text-xs` : \"fa-duotone fa-solid fa-star-christmas text-xs text-brand\"}\n aria-hidden=\"true\"\n />\n {insight.actionLabel ?? \"Ask Leo\"}\n </Button>\n </InsightDefaultTooltip>\n </div>\n </div>\n )}\n </Card>\n )}\n </div>\n </>\n )}\n </div>\n </div>\n )\n}\n\nfunction chunkMetricPairs(metrics: MetricItem[]): MetricItem[][] {\n const out: MetricItem[][] = []\n for (let i = 0; i < metrics.length; i += 2) out.push(metrics.slice(i, i + 2))\n return out\n}\n\n/* ── Main component ───────────────────────────────────────────────────────── */\n\nexport function KeyMetrics({\n variant = \"card\",\n title = \"Key Metrics\",\n description = \"Overview of performance indicators\",\n metrics = [],\n insight,\n periods = DEFAULT_PERIODS,\n defaultPeriod = \"week\",\n onPeriodChange,\n showHeader = true,\n insightCompact = false,\n insightFullWidth = false,\n metricsSingleRow = false,\n metricsHalfWidthLayout = false,\n className,\n}: KeyMetricsProps) {\n const [period, setPeriod] = React.useState(defaultPeriod)\n // Pull the host app's \"default insight action\" (e.g. toggle Ask Leo\n // sidebar) and label out of `KeyMetricsProvider` instead of\n // hardcoding `useAskLeo()`. When no provider is mounted, the default\n // action button hides entirely so the strip stays useful in apps\n // without an AI assistant.\n const {\n defaultInsightAction,\n defaultActionLabel = \"Ask Leo\",\n } = useKeyMetricsContext()\n\n function handlePeriodChange(v: string) {\n setPeriod(v)\n onPeriodChange?.(v)\n }\n\n /* Split metrics into rows of 3, or paired rows when half-width + single row, else one row */\n const rows: MetricItem[][] = metricsSingleRow\n ? metrics.length\n ? metricsHalfWidthLayout\n ? chunkMetricPairs(metrics)\n : [metrics]\n : []\n : (() => {\n const out: MetricItem[][] = []\n for (let i = 0; i < metrics.length; i += 3) {\n out.push(metrics.slice(i, i + 3))\n }\n return out\n })()\n\n const metricsCellSurfaceClassName =\n variant === \"flat\"\n ? \"bg-transparent\"\n : \"bg-card dark:bg-transparent\"\n\n const innerProps: InnerProps = {\n title,\n description,\n period,\n periods,\n metrics,\n rows,\n insight,\n onPeriodChange: handlePeriodChange,\n insightCompact,\n insightFullWidth,\n metricsSingleRow,\n metricsHalfWidthLayout,\n metricsCellSurfaceClassName,\n surfaceVariant: variant === \"flat\" ? \"flat\" : \"default\",\n }\n\n /*\n * ── GLOW GUIDELINE ────────────────────────────────────────────────────────\n * The bottom-glow treatment is a deliberate design signal. Use it only for:\n *\n * 1. AI / intelligence surfaces — e.g. AI Insights, Ask Leo responses,\n * any card that surfaces machine-generated content.\n * Opacity: 0.12–0.16 (subtle; the glow should not dominate)\n *\n * 2. Designer-designated hero sections — e.g. Key Metrics (the primary\n * KPI band), onboarding completion, or any section the product team\n * explicitly wants to \"elevate\" visually.\n * Opacity: 0.18–0.24 (more pronounced; intentional focal point)\n *\n * Do NOT add glow to:\n * • Standard data/content cards (Tasks, Activity, Learn, Charts…)\n * • Navigation or shell elements\n * • Cards that already use a coloured border or badge for status\n *\n * Implementation:\n * style={{ background: \"radial-gradient(ellipse 110% 90% at 50% 100%,\n * oklch(from var(--brand-color) l c h / <opacity>) 0%, transparent 68%)\" }}\n * + className=\"overflow-hidden\" ← required to clip the gradient\n * ─────────────────────────────────────────────────────────────────────────\n */\n const glowStyle: React.CSSProperties = {\n background: \"var(--key-metrics-card-glow-radial)\",\n }\n\n /** List-page KPI band — transparent; only `--key-metrics-flat-band-radial` glow. */\n const flatBandStyle: React.CSSProperties = {\n background: \"var(--key-metrics-flat-band-radial)\",\n boxShadow: \"var(--key-metrics-flat-band-shadow)\",\n }\n\n /* ── Card variant — ChartCard-style chrome ───────────────────────────── */\n if (variant === \"card\") {\n return (\n <Card className={cn(\"shadow-xs overflow-hidden flex flex-col\", className)} style={glowStyle}>\n <CardHeader className={cn(\"shrink-0 pb-2\", metricsHalfWidthLayout && \"space-y-2\")}>\n <div\n className={cn(\n \"flex gap-2\",\n metricsHalfWidthLayout\n ? \"flex-col min-[400px]:flex-row min-[400px]:items-start min-[400px]:justify-between\"\n : \"items-start\",\n )}\n >\n <div className=\"flex-1 min-w-0\">\n <CardTitle className=\"text-sm font-semibold leading-tight\">{title}</CardTitle>\n <CardDescription className=\"text-xs mt-0.5\">{description}</CardDescription>\n </div>\n <div className=\"flex flex-wrap items-center gap-1.5 shrink-0\">\n {defaultInsightAction ? (\n <InsightDefaultTooltip actionLabel={defaultActionLabel}>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-7 shrink-0 text-xs gap-1.5 px-2\"\n aria-label={`${defaultActionLabel} about these metrics`}\n onClick={defaultInsightAction}\n type=\"button\"\n >\n <i className=\"fa-duotone fa-solid fa-star-christmas text-xs text-brand\" aria-hidden=\"true\" />\n <span>{defaultActionLabel}</span>\n </Button>\n </InsightDefaultTooltip>\n ) : null}\n <Select value={period} onValueChange={handlePeriodChange}>\n <SelectTrigger\n size=\"sm\"\n className=\"w-auto min-w-[9rem] shrink-0 text-sm\"\n aria-label=\"Select comparison period\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\" sideOffset={4}>\n {periods.map((p) => (\n <SelectItem key={p.value} value={p.value}>\n {p.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"flex-1 pb-4\">\n <KeyMetricsInner {...innerProps} showHeader={false} />\n </CardContent>\n </Card>\n )\n }\n\n /* ── Compact variant — card chrome, no header, metrics only ──────────── */\n if (variant === \"compact\") {\n return (\n <Card className={cn(\"shadow-xs overflow-hidden\", className)} style={glowStyle}>\n <CardContent className=\"py-3 px-4\">\n <KeyMetricsInner {...innerProps} showHeader={false} />\n </CardContent>\n </Card>\n )\n }\n\n /* ── Flat variant — no surface; bottom brand glow only ── */\n return (\n <section\n aria-label={title}\n className={cn(\"relative w-full overflow-hidden pt-5 pb-8\", className)}\n style={flatBandStyle}\n >\n <KeyMetricsInner\n {...innerProps}\n innerPadding=\"px-4 lg:px-6\"\n showHeader={showHeader}\n />\n </section>\n )\n}\n\n/**\n * KeyMetricsContent — renders just the metrics grid + optional insight panel.\n * No card wrapper, no header, no period selector.\n * Designed for embedding inside a ChartCard with tabOptions period tabs.\n */\nexport function KeyMetricsContent({\n metrics = [],\n insight,\n insightCompact = false,\n insightFullWidth = false,\n}: Pick<KeyMetricsProps, \"metrics\" | \"insight\" | \"insightCompact\" | \"insightFullWidth\">) {\n const rows: MetricItem[][] = []\n for (let i = 0; i < metrics.length; i += 3) rows.push(metrics.slice(i, i + 3))\n\n return (\n <KeyMetricsInner\n title=\"\"\n description=\"\"\n period=\"\"\n periods={[]}\n metrics={metrics}\n rows={rows}\n insight={insight}\n onPeriodChange={() => {}}\n showHeader={false}\n insightCompact={insightCompact}\n insightFullWidth={insightFullWidth}\n metricsCellSurfaceClassName=\"bg-card dark:bg-transparent\"\n />\n )\n}\n"]}
1
+ {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/card.tsx","../../../src/components/ui/select.tsx","../../../src/components/ui/separator.tsx","../../../src/components/ui/button.tsx","../../../src/components/ui/tooltip.tsx","../../../src/components/ui/key-metrics-context.tsx","../../../src/components/ui/key-metrics.tsx"],"names":["jsx","SelectPrimitive","SeparatorPrimitive","React","TooltipPrimitive","jsxs","memo","React3","MetricCell","Fragment"],"mappings":";;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACgCA,SAAS,IAAA,CAAK;AAAA,EACZ,SAAA;AAAA,EACA,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EAA8D;AAC5D,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,MAAA;AAAA,MACV,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,EAAA;AAAA,QACT,sVAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,UAAA,CAAW,EAAE,SAAA,EAAW,GAAG,OAAM,EAAgC;AACxE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,aAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,oSAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,SAAA,CAAU,EAAE,SAAA,EAAW,GAAG,OAAM,EAAgC;AACvE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,YAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,gFAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,eAAA,CAAgB,EAAE,SAAA,EAAW,GAAG,OAAM,EAAgC;AAC7E,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,kBAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,MACvD,GAAG;AAAA;AAAA,GACN;AAEJ;AAeA,SAAS,WAAA,CAAY,EAAE,SAAA,EAAW,GAAG,OAAM,EAAgC;AACzE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,qCAAA,EAAuC,SAAS,CAAA;AAAA,MAC7D,GAAG;AAAA;AAAA,GACN;AAEJ;ACzGA,SAAS,MAAA,CAAO;AAAA,EACd,GAAG;AACL,CAAA,EAAsD;AACpD,EAAA,uBAAOA,IAACC,QAAA,CAAgB,IAAA,EAAhB,EAAqB,WAAA,EAAU,QAAA,EAAU,GAAG,KAAA,EAAO,CAAA;AAC7D;AAeA,SAAS,WAAA,CAAY;AAAA,EACnB,GAAG;AACL,CAAA,EAAuD;AACrD,EAAA,uBAAOD,IAACC,QAAA,CAAgB,KAAA,EAAhB,EAAsB,WAAA,EAAU,cAAA,EAAgB,GAAG,KAAA,EAAO,CAAA;AACpE;AAEA,SAAS,aAAA,CAAc;AAAA,EACrB,SAAA;AAAA,EACA,IAAA,GAAO,SAAA;AAAA,EACP,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAEG;AACD,EAAA,uBACE,IAAA;AAAA,IAACA,QAAA,CAAgB,OAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,gBAAA;AAAA,MACV,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,EAAA;AAAA,QACT,g0BAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACDD,GAAAA,CAACC,QAAA,CAAgB,IAAA,EAAhB,EAAqB,OAAA,EAAO,IAAA,EAC3B,QAAA,kBAAAD,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,2EAAA,EAA4E,aAAA,EAAY,QAAO,CAAA,EAC9G;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,SAAS,aAAA,CAAc;AAAA,EACrB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA,GAAW,cAAA;AAAA,EACX,KAAA,GAAQ,QAAA;AAAA,EACR,GAAG;AACL,CAAA,EAAyD;AACvD,EAAA,uBACEA,GAAAA,CAACC,QAAA,CAAgB,MAAA,EAAhB,EACC,QAAA,kBAAA,IAAA;AAAA,IAACA,QAAA,CAAgB,OAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,gBAAA;AAAA,MACV,sBAAoB,QAAA,KAAa,cAAA;AAAA,MACjC,WAAW,EAAA,CAAG,ikBAAA,EAAmkB,QAAA,KAAY,QAAA,IAAU,2MAA2M,SAAU,CAAA;AAAA,MAC5zB,QAAA;AAAA,MACA,KAAA;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAAD,IAAC,oBAAA,EAAA,EAAqB,CAAA;AAAA,wBACtBA,GAAAA;AAAA,UAACC,QAAA,CAAgB,QAAA;AAAA,UAAhB;AAAA,YACC,eAAA,EAAe,QAAA;AAAA,YACf,SAAA,EAAW,EAAA;AAAA,cACT,oJAAA;AAAA,cACA,aAAa,QAAA,IAAY;AAAA,aAC3B;AAAA,YAEC;AAAA;AAAA,SACH;AAAA,wBACAD,IAAC,sBAAA,EAAA,EAAuB;AAAA;AAAA;AAAA,GAC1B,EACF,CAAA;AAEJ;AAeA,SAAS,UAAA,CAAW;AAAA,EAClB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAsD;AACpD,EAAA,uBACE,IAAA;AAAA,IAACC,QAAA,CAAgB,IAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,aAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,6dAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAAD,IAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4EAAA,EACd,QAAA,kBAAAA,IAACC,QAAA,CAAgB,aAAA,EAAhB,EACC,QAAA,kBAAAD,IAAC,GAAA,EAAA,EAAE,SAAA,EAAU,yCAAwC,aAAA,EAAY,MAAA,EAAO,GAC1E,CAAA,EACF,CAAA;AAAA,wBACAA,GAAAA,CAACC,QAAA,CAAgB,QAAA,EAAhB,EAA0B,QAAA,EAAS;AAAA;AAAA;AAAA,GACtC;AAEJ;AAeA,SAAS,oBAAA,CAAqB;AAAA,EAC5B,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgE;AAC9D,EAAA,uBACED,GAAAA;AAAA,IAACC,QAAA,CAAgB,cAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,yBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,2GAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,kBAAAD,GAAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UAAE,SAAA,EAAU,wBAAA;AAAA,UAAyB,aAAA,EAAY;AAAA;AAAA;AAClD;AAAA,GACF;AAEJ;AAEA,SAAS,sBAAA,CAAuB;AAAA,EAC9B,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAkE;AAChE,EAAA,uBACEA,GAAAA;AAAA,IAACC,QAAA,CAAgB,gBAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,2BAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,2GAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,kBAAAD,GAAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UAAE,SAAA,EAAU,0BAAA;AAAA,UAA2B,aAAA,EAAY;AAAA;AAAA;AACpD;AAAA,GACF;AAEJ;AC1KA,SAAS,SAAA,CAAU;AAAA,EACjB,SAAA;AAAA,EACA,WAAA,GAAc,YAAA;AAAA,EACd,UAAA,GAAa,IAAA;AAAA,EACb,GAAG;AACL,CAAA,EAAyD;AACvD,EAAA,uBACEA,GAAAA;AAAA,IAACE,WAAA,CAAmB,IAAA;AAAA,IAAnB;AAAA,MACC,WAAA,EAAU,WAAA;AAAA,MACV,UAAA;AAAA,MACA,WAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,sKAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;ACnBA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,ulBAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,wDAAA;AAAA,QACT,OAAA,EACE,0NAAA;AAAA,QACF,SAAA,EACE,iIAAA;AAAA,QACF,KAAA,EACE,8LAAA;AAAA,QACF,WAAA,EACE,6NAAA;AAAA,QACF,IAAA,EAAM;AAAA,OACR;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EACE,wFAAA;AAAA,QACF,EAAA,EAAI,0KAAA;AAAA,QACJ,EAAA,EAAI,8KAAA;AAAA,QACJ,EAAA,EAAI,yFAAA;AAAA,QACJ,IAAA,EAAM,QAAA;AAAA,QACN,SAAA,EACE,oFAAA;AAAA,QACF,SAAA,EACE,+CAAA;AAAA,QACF,SAAA,EAAW;AAAA;AACb,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ,CAAA;AAEA,IAAM,MAAA,GAAeC,MAAA,CAAA,UAAA,CAMnB,CAAC,EAAE,WAAW,OAAA,GAAU,SAAA,EAAW,IAAA,GAAO,SAAA,EAAW,OAAA,GAAU,KAAA,EAAO,GAAG,KAAA,IAAS,GAAA,KAAQ;AAC1F,EAAA,MAAM,IAAA,GAAO,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,QAAA;AAEnC,EAAA,uBACEH,GAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,WAAA,EAAU,QAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,GAAG,SAAS,CAAA;AAAA,MACzD,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC,CAAA;AACD,MAAA,CAAO,WAAA,GAAc,QAAA;AC3CrB,SAAS,OAAA,CAAQ;AAAA,EACf,GAAG;AACL,CAAA,EAAuD;AACrD,EAAA,uBAAOA,IAACI,SAAA,CAAiB,IAAA,EAAjB,EAAsB,WAAA,EAAU,SAAA,EAAW,GAAG,KAAA,EAAO,CAAA;AAC/D;AAEA,SAAS,cAAA,CAAe;AAAA,EACtB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA0D;AACxD,EAAA,uBACEJ,GAAAA;AAAA,IAACI,SAAA,CAAiB,OAAA;AAAA,IAAjB;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,wBAAA,EAAwB,IAAA;AAAA,MACxB,SAAA,EAAW,EAAA,CAAG,gBAAA,EAAkB,SAAS,CAAA;AAAA,MACxC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,cAAA,CAAe;AAAA,EACtB,SAAA;AAAA,EACA,UAAA,GAAa,CAAA;AAAA,EACb,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA0D;AACxD,EAAA,uBACEJ,GAAAA,CAACI,SAAA,CAAiB,MAAA,EAAjB,EACC,QAAA,kBAAAC,IAAAA;AAAA,IAACD,SAAA,CAAiB,OAAA;AAAA,IAAjB;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,UAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,2rBAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACDJ,GAAAA,CAACI,SAAA,CAAiB,KAAA,EAAjB,EAAuB,WAAU,oGAAA,EAAqG;AAAA;AAAA;AAAA,GACzI,EACF,CAAA;AAEJ;ACfA,IAAM,iBAAA,GAA0B,MAAA,CAAA,aAAA,CAAsC,EAAE,CAAA;AAGjE,SAAS,oBAAA,GAA+C;AAC7D,EAAA,OAAa,kBAAW,iBAAiB,CAAA;AAC3C;AAEO,SAAS,kBAAA,CAAmB;AAAA,EACjC,KAAA;AAAA,EACA;AACF,CAAA,EAGG;AAID,EAAA,MAAME,KAAAA,GAAa,MAAA,CAAA,OAAA;AAAA,IACjB,OAAO;AAAA,MACL,sBAAsB,KAAA,CAAM,oBAAA;AAAA,MAC5B,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,oBAAoB,KAAA,CAAM;AAAA,KAC5B,CAAA;AAAA,IACA,CAAC,KAAA,CAAM,oBAAA,EAAsB,KAAA,CAAM,YAAA,EAAc,MAAM,kBAAkB;AAAA,GAC3E;AACA,EAAA,uBACEN,GAAAA,CAAC,iBAAA,CAAkB,UAAlB,EAA2B,KAAA,EAAOM,OAChC,QAAA,EACH,CAAA;AAEJ;ACzBA,SAAS,qBAAA,CAAsB;AAAA,EAC7B,WAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,MAAM,EAAE,YAAA,EAAc,kBAAA,GAAqB,SAAA,KAAc,oBAAA,EAAqB;AAC9E,EAAA,MAAM,QAAQ,WAAA,IAAe,kBAAA;AAC7B,EAAA,MAAM,eACJ,CAAC,CAAC,YAAA,KAAiB,CAAC,eAAe,WAAA,KAAgB,kBAAA,CAAA;AACrD,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,uBACED,KAAC,OAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAL,GAAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAO,IAAA,EAAE,QAAA,EAAS,CAAA;AAAA,sBAClCA,GAAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAK,OAAO,QAAA,EAAA,KAAA,EAAM;AAAA,KAAA,EACpC,CAAA;AAAA,EAEJ;AACA,EAAA,uBACEK,KAAC,OAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAL,GAAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAO,IAAA,EAAE,QAAA,EAAS,CAAA;AAAA,oBAClCK,IAAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAK,KAAA,EAAM,WAAU,qCAAA,EACnC,QAAA,EAAA;AAAA,sBAAAL,GAAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,MACZ;AAAA,KAAA,EACH;AAAA,GAAA,EACF,CAAA;AAEJ;AAeO,SAAS,eAAA,CACd,KAAA,EACA,QAAA,GAAgC,kBAAA,EACf;AACjB,EAAA,IAAI,KAAA,KAAU,WAAW,OAAO,OAAA;AAChC,EAAA,IAAI,QAAA,KAAa,iBAAiB,OAAO,OAAA;AACzC,EAAA,IAAI,aAAa,kBAAA,EAAoB;AACnC,IAAA,OAAO,KAAA,KAAU,OAAO,UAAA,GAAa,UAAA;AAAA,EACvC;AACA,EAAA,OAAO,KAAA,KAAU,OAAO,UAAA,GAAa,UAAA;AACvC;AAGO,SAAS,wBAAA,CACd,KAAA,EACA,QAAA,GAAgC,kBAAA,EACxB;AACR,EAAA,IAAI,KAAA,KAAU,WAAW,OAAO,eAAA;AAChC,EAAA,IAAI,aAAa,eAAA,EAAiB;AAChC,IAAA,OAAO,KAAA,KAAU,OAAO,WAAA,GAAc,WAAA;AAAA,EACxC;AACA,EAAA,IAAI,aAAa,kBAAA,EAAoB;AACnC,IAAA,OAAO,KAAA,KAAU,OAAO,sBAAA,GAAyB,wBAAA;AAAA,EACnD;AACA,EAAA,OAAO,KAAA,KAAU,OAAO,wBAAA,GAA2B,sBAAA;AACrD;AAsIA,SAAS,wBAAA,CACP,WACA,sBAAA,EACQ;AACR,EAAA,IAAI,SAAA,IAAa,GAAG,OAAO,OAAA;AAE3B,EAAA,MAAM,WAAA,GAAc,sDAAA;AAEpB,EAAA,IAAI,cAAc,CAAA,EAAG;AACnB,IAAA,OAAO,EAAA,CAAG,OAAA,EAAS,WAAA,EAAa,4BAA4B,CAAA;AAAA,EAC9D;AAEA,EAAA,IAAI,cAAc,CAAA,EAAG;AACnB,IAAA,MAAM,SAAA,GAAY,yBACd,uBAAA,GACA,uBAAA;AACJ,IAAA,OAAO,EAAA;AAAA,MACL,OAAA;AAAA,MACA,WAAA;AAAA;AAAA,MAEA,iCAAA;AAAA;AAAA,MAEA,GAAG,SAAS,CAAA,kCAAA,CAAA;AAAA,MACZ,GAAG,SAAS,CAAA,8BAAA,CAAA;AAAA,MACZ,GAAG,SAAS,CAAA,0CAAA;AAAA,KACd;AAAA,EACF;AAEA,EAAA,OAAO,EAAA,CAAG,OAAA,EAAS,WAAA,EAAa,iCAAiC,CAAA;AACnE;AAEA,SAAS,sBAAA,CAAuB,WAAmB,sBAAA,EAAyC;AAC1F,EAAA,MAAM,IAAA,GAAO,sBAAA;AACb,EAAA,QAAQ,SAAA;AAAW,IACjB,KAAK,CAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,CAAA;AACH,MAAA,OAAO,OACH,kCAAA,GACA,kCAAA;AAAA,IACN,KAAK,CAAA;AAEH,MAAA,OAAO,OACH,kCAAA,GACA,kCAAA;AAAA,IACN,KAAK,CAAA;AAKH,MAAA,OAAO,OACH,uDAAA,GACA,uDAAA;AAAA,IACN;AAGE,MAAA,OAAO,OACH,4EAAA,GACA,4EAAA;AAAA;AAEV;AAIA,IAAM,eAAA,GAAkC;AAAA,EACtC,EAAE,KAAA,EAAO,MAAA,EAAW,KAAA,EAAO,cAAA,EAAkB;AAAA,EAC7C,EAAE,KAAA,EAAO,OAAA,EAAW,KAAA,EAAO,eAAA,EAAkB;AAAA,EAC7C,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,iBAAA,EAAkB;AAAA,EAC7C,EAAE,KAAA,EAAO,MAAA,EAAW,KAAA,EAAO,cAAA;AAC7B,CAAA;AAKA,IAAM,UAAA,GAAmBO,MAAA,CAAA,IAAA,CAAK,SAASC,WAAAA,CAAW;AAAA,EAChD,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,aAAA,GAAgB,kBAAA;AAAA,EAChB,WAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA,GAAgB,SAAA;AAAA,EAChB,KAAA,GAAQ,KAAA;AAAA,EACR,UAAA,GAAa;AACf,CAAA,EAAuE;AACrE,EAAA,MAAM,OAAa,KAAA,KAAU,IAAA;AAC7B,EAAA,MAAM,SAAa,KAAA,KAAU,MAAA;AAC7B,EAAA,MAAM,IAAA,GAAc,eAAA,CAAgB,KAAA,EAAO,aAAa,CAAA;AACxD,EAAA,MAAM,aAAA,GAAgB,CAAC,EAAE,IAAA,IAAQ,OAAA,CAAA;AACjC,EAAA,MAAM,SAAa,aAAA,KAAkB,MAAA;AAKrC,EAAA,MAAM,SAAA,GAAY,OAAO,KAAA,KAAU,QAAA,GAC9B,UAAU,CAAA,GAAI,EAAA,GAAK,MAAA,CAAO,KAAK,CAAA,GAChC,MAAA,CAAO,KAAA,IAAS,EAAE,EAAE,IAAA,EAAK;AAC7B,EAAA,MAAM,aAAA,GAAgB,IAAA,IAAQ,MAAA,IAAU,SAAA,CAAU,MAAA,GAAS,CAAA;AAE3D,EAAA,MAAM,KAAA,mBACJH,IAAAA,CAAAI,QAAAA,EAAA,EAEE,QAAA,EAAA;AAAA,oBAAAJ,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,mEAAA;AAAA,UACA,QAAQ,kBAAA,GAAqB;AAAA,SAC/B;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAL,GAAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,4DAAA;AAAA,gBACA,QAAQ,SAAA,GAAY,SAAA;AAAA,gBACpB,MAAA,IAAU;AAAA,eACZ;AAAA,cAEC,QAAA,EAAA;AAAA;AAAA,WACH;AAAA,UACC,aAAA,mBACCA,GAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,6BAAA,EAA8B,aAAA,EAAY,MAAA,EACxD,QAAA,kBAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,gKAAA,EAAiK,GAChL,CAAA,GACE;AAAA;AAAA;AAAA,KACN;AAAA,oBAGAK,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qCAAA,EACb,QAAA,EAAA;AAAA,sBAAAL,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,EAAA;AAAA,YACT,qDAAA;AAAA,YACA,KAAA,GACI,MAAA,GACE,oBAAA,GACA,sBAAA,GACF,SACE,6BAAA,GACA;AAAA,WACR;AAAA,UAEC,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,MAKC,iCACCK,IAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,EAAA;AAAA,YACT,yDAAA;AAAA,YACA,QAAQ,oBAAA,GAAuB,oBAAA;AAAA,YAC/B,SAAS,UAAA,IAAc,cAAA;AAAA,YACvB,SAAS,UAAA,IAAc,kBAAA;AAAA,YACvB,SAAS,OAAA,IAAW;AAAA,WACtB;AAAA,UACA,YAAA,EAAY,GAAG,wBAAA,CAAyB,KAAA,EAAO,aAAa,CAAC,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,UAEjF,QAAA,EAAA;AAAA,YAAA,IAAA,oBAAUL,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,0CAAA,EAA6C,eAAY,MAAA,EAAO,CAAA;AAAA,YACvF,0BAAUA,GAAAA,CAAC,OAAE,SAAA,EAAU,4CAAA,EAA6C,eAAY,MAAA,EAAO,CAAA;AAAA,YACvF,CAAC,IAAA,IAAQ,CAAC,MAAA,IAAU,SAAA,CAAU,MAAA,GAAS,CAAA,oBACtCA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iCAAA,EAAkC,eAAY,MAAA,EAAO,CAAA;AAAA,YAEnE,UAAU,MAAA,GAAS,CAAA,oBAAKA,GAAAA,CAAC,UAAM,QAAA,EAAA,SAAA,EAAU;AAAA;AAAA;AAAA;AAC5C,KAAA,EAEJ,CAAA;AAAA,IAIC,8BACCA,GAAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,4DAAA;AAAA,UACA,QAAQ,aAAA,GAAgB;AAAA,SAC1B;AAAA,QAEC,QAAA,EAAA;AAAA;AAAA,KACH,GACE;AAAA,GAAA,EACN,CAAA;AAGF,EAAA,MAAM,WAAA,GAAc,EAAA;AAAA,IAClB,2DAAA;AAAA,IACA,UAAA,IAAc,sBAAA;AAAA,IACd,QAAQ,mCAAA,GAAsC,iCAAA;AAAA,IAC9C,MAAA,IAAU,SAAA;AAAA,IACV,aAAA,IAAiB;AAAA,MACf,+CAAA;AAAA,MACA,uBAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,uBACEA,GAAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAY,SAAA,EAAW,WAAA,EAAa,YAAA,EAAY,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,EAClE,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,uBACEA,GAAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,UAAS,OAAA,EAAkB,SAAA,EAAW,WAAA,EAAa,YAAA,EAAY,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,KAAK,IAC3F,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,uBAAOA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,aAAc,QAAA,EAAA,KAAA,EAAM,CAAA;AAC7C,CAAC,CAAA;AAGD,SAAS,gBAAgB,OAAA,EAAgC;AACvD,EAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,WAAA,EAAa,IAAA,EAAK;AACpC,EAAA,IAAI,GAAG,OAAO,CAAA;AACd,EAAA,OAAO,OAAA,CAAQ,SAAA,EAAW,IAAA,EAAK,IAAK,EAAA;AACtC;AAKA,SAAS,0BAAA,CAA2B;AAAA,EAClC,OAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,MAAM,SAAA,GAAY,UAAU,IAAA,GAAO,SAAA;AACnC,EAAA,MAAM,OAAA,GAAU,UACZ,gEAAA,GACA,SAAA;AACJ,EAAA,MAAM,IAAA,GAAO,gBAAgB,OAAO,CAAA;AAEpC,EAAA,uBACEA,GAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,YAAA,EAAW,SAAA;AAAA,MACX,SAAA,EAAW,EAAA;AAAA,QACT,2GAAA;AAAA,QACA;AAAA,OACF;AAAA,MAGA,QAAA,kBAAAK,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wDAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAA,EACb,QAAA,EAAA;AAAA,0BAAAL,IAAC,YAAA,EAAA,EAAa,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,MAAM,SAAA,EAAW,CAAA;AAAA,0BAC3DK,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,EAAA;AAAA,4BAAAL,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oDAAA,EAAsD,kBAAQ,KAAA,EAAM,CAAA;AAAA,YAChF,uBACCA,GAAAA,CAAC,OAAE,SAAA,EAAU,iDAAA,EAAmD,gBAAK,CAAA,GACnE;AAAA,WAAA,EACN,CAAA;AAAA,UACC,OAAA,CAAQ,wBACPA,GAAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,MAAM,OAAA,CAAQ,IAAA;AAAA,cACd,SAAA,EAAU,6KAAA;AAAA,cACV,YAAA,EAAY,CAAA,KAAA,EAAQ,OAAA,CAAQ,KAAK,CAAA,eAAA,CAAA;AAAA,cAEjC,0BAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oCAAA,EAAqC,eAAY,MAAA,EAAO;AAAA;AAAA;AACvE,SAAA,EAEJ,CAAA;AAAA,wBAEAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wCAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,qBAAA,EAAA,EAAsB,WAAA,EAAa,OAAA,CAAQ,WAAA,EAC1C,QAAA,kBAAAK,IAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,UAAU,SAAA,GAAY,OAAA;AAAA,YAC/B,IAAA,EAAK,IAAA;AAAA,YACL,SAAA,EAAW,EAAA;AAAA,cACT,sCAAA;AAAA,cACA,UACI,yEAAA,GACA;AAAA,aACN;AAAA,YACA,SAAS,OAAA,CAAQ,QAAA;AAAA,YACjB,YAAA,EAAY,QAAQ,WAAA,IAAe,SAAA;AAAA,YAEnC,QAAA,EAAA;AAAA,8BAAAL,GAAAA;AAAA,gBAAC,GAAA;AAAA,gBAAA;AAAA,kBACC,WACE,OAAA,CAAQ,UAAA,GACJ,CAAA,SAAA,EAAY,OAAA,CAAQ,UAAU,CAAA,QAAA,CAAA,GAC9B,0DAAA;AAAA,kBAEN,aAAA,EAAY;AAAA;AAAA,eACd;AAAA,cACC,QAAQ,WAAA,IAAe;AAAA;AAAA;AAAA,WAE5B,CAAA,EACF;AAAA,OAAA,EACF;AAAA;AAAA,GACF;AAEJ;AAIA,SAAS,YAAA,CAAa;AAAA,EACpB,QAAA,GAAW,SAAA;AAAA,EACX,IAAA,GAAO;AACT,CAAA,EAGG;AACD,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,OAAA,EAAS;AAAA,MACP,EAAA,EAAI,yCAAA;AAAA,MACJ,IAAA,EAAM,uBAAA;AAAA,MACN,KAAA,EAAO;AAAA,KACT;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,EAAA,EAAI,sCAAA;AAAA,MACJ,IAAA,EAAM,gBAAA;AAAA,MACN,KAAA,EAAO;AAAA,KACT;AAAA,IACA,OAAO,EAAE,EAAA,EAAI,qBAAqB,IAAA,EAAM,iBAAA,EAAmB,OAAO,kBAAA;AAAmB,IACrF,QAAQ,CAAA;AAEV,EAAA,uBACEA,GAAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,+DAAA;AAAA,QACA,IAAA,KAAS,OAAO,iBAAA,GAAoB,iBAAA;AAAA,QACpC,MAAA,CAAO,EAAA;AAAA,QACP,MAAA,CAAO;AAAA,OACT;AAAA,MACA,aAAA,EAAY,MAAA;AAAA,MAEZ,0BAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAW,CAAA,SAAA,EAAY,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI;AAAA;AAAA,GAC3C;AAEJ;AA4BA,SAAS,eAAA,CAAgB;AAAA,EACvB,KAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA,GAAe,EAAA;AAAA,EACf,UAAA,GAAa,IAAA;AAAA,EACb,cAAA,GAAiB,KAAA;AAAA,EACjB,gBAAA,GAAmB,KAAA;AAAA,EACnB,gBAAA,GAAmB,KAAA;AAAA,EACnB,sBAAA,GAAyB,KAAA;AAAA,EACzB,2BAAA,GAA8B,eAAA;AAAA,EAC9B,cAAA,GAAiB;AACnB,CAAA,EAAe;AACb,EAAA,MAAM,aAAa,cAAA,KAAmB,MAAA;AACtC,EAAA,MAAM,uBAAuB,UAAA,GACzB,wBAAA,CAAyB,OAAA,CAAQ,MAAA,EAAQ,sBAAsB,CAAA,GAC/D,kBAAA;AAEJ,EAAA,MAAM,iBAAA,GAAoB,OAAA,IAAW,CAAC,gBAAA,IAAoB,CAAC,sBAAA;AAC3D,EAAA,MAAM,kBAAA,GAAqB,OAAA,IAAW,CAAC,gBAAA,IAAoB,sBAAA;AAE3D,EAAA,uBACEK,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,aAAA,EAAc,WAAU,UAAA,EAEpC,QAAA,EAAA;AAAA,IAAA,UAAA,oBACCA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA;AAAA,MACd,0BAAA;AAAA,MACA,yDAAA;AAAA,MACA;AAAA,KACF,EACE,QAAA,EAAA;AAAA,sBAAAA,KAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAL,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uDAAA,EAAyD,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,wBAC5EA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wCAAwC,QAAA,EAAA,WAAA,EAAY;AAAA,OAAA,EACnE,CAAA;AAAA,sBAGAK,IAAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,eAAe,cAAA,EACpC,QAAA,EAAA;AAAA,wBAAAL,GAAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,uDAAA;AAAA,YACV,YAAA,EAAW,0BAAA;AAAA,YAEX,QAAA,kBAAAA,IAAC,WAAA,EAAA,EAAY;AAAA;AAAA,SACf;AAAA,wBACAA,IAAC,aAAA,EAAA,EAAc,KAAA,EAAM,OAAM,UAAA,EAAY,CAAA,EACpC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,qBACZA,GAAAA,CAAC,UAAA,EAAA,EAAyB,OAAO,CAAA,CAAE,KAAA,EAChC,YAAE,KAAA,EAAA,EADY,CAAA,CAAE,KAEnB,CACD,CAAA,EACH;AAAA,OAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,oBAIFK,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,qBAAA;AAAA;AAAA,UAEA,iBAAA,IACE,+FAAA;AAAA,UACF;AAAA,SACF;AAAA,QAIA,QAAA,EAAA;AAAA,0BAAAA,IAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,wCAAA;AAAA,gBACA,CAAC,iBAAA,IAAqB,QAAA;AAAA,gBACtB,iBAAA,IAAqB;AAAA,eACvB;AAAA,cAOC,QAAA,EAAA;AAAA,gBAAA,sBAAA,mBACCL,GAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAW,EAAA;AAAA,sBACT,yCAAA;AAAA,sBACA,gBAAA,GACI,sBAAA;AAAA,wBAAuB,OAAA,CAAQ,MAAA;AAAA;AAAA,wBAAmB;AAAA,uBAAI,GACtD,aAAA;AAAA,sBACJ;AAAA,qBACF;AAAA,oBAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,qBACZA,IAAC,KAAA,EAAA,EAAe,SAAA,EAAW,EAAA,CAAG,SAAA,EAAW,2BAA2B,CAAA,EAClE,0BAAAA,GAAAA,CAAC,UAAA,EAAA,EAAY,GAAG,CAAA,EAAG,KAAA,EAAK,IAAA,EAAC,YAAY,KAAA,EAAO,CAAA,EAAA,EADpC,CAAA,CAAE,EAEZ,CACD;AAAA;AAAA,oCAGHA,GAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAW,EAAA;AAAA,sBACT,yCAAA;AAAA,sBACA,sBAAA;AAAA,wBAAuB,OAAA,CAAQ,MAAA;AAAA;AAAA,wBAAmB;AAAA,uBAAK;AAAA,sBACvD;AAAA,qBACF;AAAA,oBAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,qBACZA,IAAC,KAAA,EAAA,EAAe,SAAA,EAAW,EAAA,CAAG,SAAA,EAAW,2BAA2B,CAAA,EAClE,0BAAAA,GAAAA,CAAC,UAAA,EAAA,EAAY,GAAG,CAAA,EAAG,KAAA,EAAO,KAAA,EAAO,YAAY,KAAA,EAAO,CAAA,EAAA,EAD5C,CAAA,CAAE,EAEZ,CACD;AAAA;AAAA,iBACH;AAAA,gCASFA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0CAAA,EACZ,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAK,MAAA,qBACdK,IAAAA,CAAOE,iBAAN,EACE,QAAA,EAAA;AAAA,kBAAA,MAAA,GAAS,CAAA,IAAK,CAAC,UAAA,oBACdP,IAAC,SAAA,EAAA,EAAU,aAAA,EAAY,MAAA,EAAO,SAAA,EAAU,MAAA,EAAO,CAAA;AAAA,kCAEjDA,GAAAA;AAAA,oBAAC,KAAA;AAAA,oBAAA;AAAA,sBACC,SAAA,EAAW,EAAA;AAAA,wBACT,MAAA;AAAA,wBACA,sBAAA,CAAuB,GAAA,CAAI,MAAA,EAAQ,sBAAsB,CAAA;AAAA,wBACzD,UAAA,GACI,wBAAA,CAAyB,GAAA,CAAI,MAAA,EAAQ,sBAAsB,CAAA,GAC3D;AAAA,uBACN;AAAA,sBAEC,QAAA,EAAA,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,qBACRA,IAAC,KAAA,EAAA,EAAe,SAAA,EAAW,EAAA,CAAG,SAAA,EAAW,2BAA2B,CAAA,EAClE,0BAAAA,GAAAA,CAAC,UAAA,EAAA,EAAY,GAAG,CAAA,EAAG,KAAA,EAAO,sBAAA,EAAwB,YAAY,KAAA,EAAO,CAAA,EAAA,EAD7D,CAAA,CAAE,EAEZ,CACD;AAAA;AAAA;AACH,iBAAA,EAAA,EAlBmB,MAmBrB,CACD,CAAA,EACH;AAAA;AAAA;AAAA,WACF;AAAA,UAGC,OAAA,oBACCK,IAAAA,CAAAI,QAAAA,EAAA,EACG,QAAA,EAAA;AAAA,YAAA,gBAAA,mBACCT,GAAAA;AAAA,cAAC,SAAA;AAAA,cAAA;AAAA,gBACC,aAAA,EAAY,MAAA;AAAA,gBACZ,SAAA,EAAW,EAAA,CAAG,aAAA,EAAe,UAAA,IAAc,sBAAsB;AAAA;AAAA,aACnE,GACE,qCACFA,GAAAA;AAAA,cAAC,SAAA;AAAA,cAAA;AAAA,gBACC,aAAA,EAAY,MAAA;AAAA,gBACZ,SAAA,EAAW,EAAA,CAAG,aAAA,EAAe,UAAA,IAAc,sBAAsB;AAAA;AAAA,gCAGnEA,GAAAA;AAAA,cAAC,SAAA;AAAA,cAAA;AAAA,gBACC,aAAA,EAAY,MAAA;AAAA,gBACZ,SAAA,EAAW,EAAA,CAAG,gBAAA,EAAkB,UAAA,IAAc,uBAAuB;AAAA;AAAA,aACvE;AAAA,4BAGFA,GAAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAW,EAAA;AAAA,kBACT,sCAAA;AAAA;AAAA,kBAEA,iBAAA,IACE,CAAC,gBAAA,IACD,EAAA;AAAA,oBACE,mBAAA;AAAA;AAAA,oBAEA,CAAC,UAAA,IAAc;AAAA;AACjB,iBACJ;AAAA,gBAEC,QAAA,EAAA,OAAA,IAAW,CAAC,gBAAA,mBACXA,GAAAA,CAAC,8BAA2B,OAAA,EAAkB,OAAA,EAAS,cAAA,EAAgB,CAAA,mBAEvEA,GAAAA;AAAA,kBAAC,IAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,YAAA,EAAW,SAAA;AAAA,oBACX,SAAA,EAAW,EAAA;AAAA,sBACT,qEAAA;AAAA,sBACA;AAAA,qBACF;AAAA,oBAEC,QAAA,EAAA,cAAA,mBACCK,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,uGAAA,EACb,QAAA,EAAA;AAAA,sCAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACb,QAAA,EAAA;AAAA,wCAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAA,EACb,QAAA,EAAA;AAAA,0CAAAL,IAAC,YAAA,EAAA,EAAa,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,MAAK,IAAA,EAAK,CAAA;AAAA,0CACpDK,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uDAAA,EACb,QAAA,EAAA;AAAA,4CAAAL,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uDAAA,EACV,kBAAQ,KAAA,EACX,CAAA;AAAA,4BACC,OAAA,CAAQ,wBACPA,GAAAA;AAAA,8BAAC,GAAA;AAAA,8BAAA;AAAA,gCACC,MAAM,OAAA,CAAQ,IAAA;AAAA,gCACd,SAAA,EAAU,sKAAA;AAAA,gCACV,YAAA,EAAY,CAAA,KAAA,EAAQ,OAAA,CAAQ,KAAK,CAAA,eAAA,CAAA;AAAA,gCAEjC,0BAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oCAAA,EAAqC,eAAY,MAAA,EAAO;AAAA;AAAA;AACvE,2BAAA,EAEJ;AAAA,yBAAA,EACF,CAAA;AAAA,wBACC,OAAA,CAAQ,8BACPA,GAAAA,CAAC,OAAE,SAAA,EAAU,+CAAA,EACV,QAAA,EAAA,OAAA,CAAQ,WAAA,EACX,CAAA,GACE;AAAA,uBAAA,EACN,CAAA;AAAA,sCACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,qBAAA,EAAA,EAAsB,WAAA,EAAa,OAAA,CAAQ,WAAA,EAC1C,QAAA,kBAAAK,IAAAA;AAAA,wBAAC,MAAA;AAAA,wBAAA;AAAA,0BACC,OAAA,EAAQ,OAAA;AAAA,0BACR,IAAA,EAAK,IAAA;AAAA,0BACL,SAAA,EAAU,iHAAA;AAAA,0BACV,SAAS,OAAA,CAAQ,QAAA;AAAA,0BACjB,YAAA,EAAY,QAAQ,WAAA,IAAe,SAAA;AAAA,0BAEnC,QAAA,EAAA;AAAA,4CAAAL,GAAAA;AAAA,8BAAC,GAAA;AAAA,8BAAA;AAAA,gCACC,WAAW,OAAA,CAAQ,UAAA,GAAa,CAAA,SAAA,EAAY,OAAA,CAAQ,UAAU,CAAA,QAAA,CAAA,GAAa,0DAAA;AAAA,gCAC3E,aAAA,EAAY;AAAA;AAAA,6BACd;AAAA,4BACC,QAAQ,WAAA,IAAe;AAAA;AAAA;AAAA,yBAE5B,CAAA,EACF;AAAA,qBAAA,EACF,CAAA,mBAEAK,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,uGAAA,EACb,QAAA,EAAA;AAAA,sCAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACb,QAAA,EAAA;AAAA,wCAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACb,QAAA,EAAA;AAAA,0CAAAL,GAAAA,CAAC,YAAA,EAAA,EAAa,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,CAAA;AAAA,0CAC1CK,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uDAAA,EACb,QAAA,EAAA;AAAA,4CAAAL,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sDAAA,EACV,kBAAQ,KAAA,EACX,CAAA;AAAA,4BACC,OAAA,CAAQ,wBACPA,GAAAA;AAAA,8BAAC,GAAA;AAAA,8BAAA;AAAA,gCACC,MAAM,OAAA,CAAQ,IAAA;AAAA,gCACd,SAAA,EAAU,sKAAA;AAAA,gCACV,YAAA,EAAY,CAAA,KAAA,EAAQ,OAAA,CAAQ,KAAK,CAAA,eAAA,CAAA;AAAA,gCAEjC,0BAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oCAAA,EAAqC,eAAY,MAAA,EAAO;AAAA;AAAA;AACvE,2BAAA,EAEJ;AAAA,yBAAA,EACF,CAAA;AAAA,wBACC,OAAA,CAAQ,8BACPA,GAAAA,CAAC,OAAE,SAAA,EAAU,+CAAA,EACV,QAAA,EAAA,OAAA,CAAQ,WAAA,EACX,CAAA,GACE;AAAA,uBAAA,EACN,CAAA;AAAA,sCACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,qBAAA,EAAA,EAAsB,WAAA,EAAa,OAAA,CAAQ,WAAA,EAC1C,QAAA,kBAAAK,IAAAA;AAAA,wBAAC,MAAA;AAAA,wBAAA;AAAA,0BACC,OAAA,EAAQ,OAAA;AAAA,0BACR,IAAA,EAAK,IAAA;AAAA,0BACL,SAAA,EAAU,iHAAA;AAAA,0BACV,SAAS,OAAA,CAAQ,QAAA;AAAA,0BACjB,YAAA,EAAY,QAAQ,WAAA,IAAe,SAAA;AAAA,0BAEnC,QAAA,EAAA;AAAA,4CAAAL,GAAAA;AAAA,8BAAC,GAAA;AAAA,8BAAA;AAAA,gCACC,WAAW,OAAA,CAAQ,UAAA,GAAa,CAAA,SAAA,EAAY,OAAA,CAAQ,UAAU,CAAA,QAAA,CAAA,GAAa,0DAAA;AAAA,gCAC3E,aAAA,EAAY;AAAA;AAAA,6BACd;AAAA,4BACC,QAAQ,WAAA,IAAe;AAAA;AAAA;AAAA,yBAE5B,CAAA,EACF;AAAA,qBAAA,EACF;AAAA;AAAA;AAEJ;AAAA;AAEJ,WAAA,EACF;AAAA;AAAA;AAAA;AAEJ,GAAA,EACF,CAAA;AAEJ;AAEA,SAAS,iBAAiB,OAAA,EAAuC;AAC/D,EAAA,MAAM,MAAsB,EAAC;AAC7B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,IAAK,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAC5E,EAAA,OAAO,GAAA;AACT;AAIO,SAAS,UAAA,CAAW;AAAA,EACzB,OAAA,GAAgB,MAAA;AAAA,EAChB,KAAA,GAAgB,aAAA;AAAA,EAChB,WAAA,GAAgB,oCAAA;AAAA,EAChB,UAAgB,EAAC;AAAA,EACjB,OAAA;AAAA,EACA,OAAA,GAAgB,eAAA;AAAA,EAChB,aAAA,GAAgB,MAAA;AAAA,EAChB,cAAA;AAAA,EACA,UAAA,GAAgB,IAAA;AAAA,EAChB,cAAA,GAAiB,KAAA;AAAA,EACjB,gBAAA,GAAmB,KAAA;AAAA,EACnB,gBAAA,GAAmB,KAAA;AAAA,EACnB,sBAAA,GAAyB,KAAA;AAAA,EACzB;AACF,CAAA,EAAoB;AAClB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAUO,gBAAS,aAAa,CAAA;AAMxD,EAAA,MAAM;AAAA,IACJ,oBAAA;AAAA,IACA,kBAAA,GAAqB;AAAA,MACnB,oBAAA,EAAqB;AAEzB,EAAA,SAAS,mBAAmB,CAAA,EAAW;AACrC,IAAA,SAAA,CAAU,CAAC,CAAA;AACX,IAAA,cAAA,GAAiB,CAAC,CAAA;AAAA,EACpB;AAGA,EAAA,MAAM,IAAA,GAAuB,gBAAA,GACzB,OAAA,CAAQ,MAAA,GACN,sBAAA,GACE,gBAAA,CAAiB,OAAO,CAAA,GACxB,CAAC,OAAO,CAAA,GACV,MACD,MAAM;AACL,IAAA,MAAM,MAAsB,EAAC;AAC7B,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,EAAQ,KAAK,CAAA,EAAG;AAC1C,MAAA,GAAA,CAAI,KAAK,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAAA,IAClC;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,GAAG;AAEP,EAAA,MAAM,2BAAA,GACJ,OAAA,KAAY,MAAA,GACR,gBAAA,GACA,6BAAA;AAEN,EAAA,MAAM,UAAA,GAAyB;AAAA,IAC7B,KAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,cAAA,EAAgB,kBAAA;AAAA,IAChB,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,gBAAA;AAAA,IACA,sBAAA;AAAA,IACA,2BAAA;AAAA,IACA,cAAA,EAAgB,OAAA,KAAY,MAAA,GAAS,MAAA,GAAS;AAAA,GAChD;AA0BA,EAAA,MAAM,SAAA,GAAiC;AAAA,IACrC,UAAA,EAAY;AAAA,GACd;AAGA,EAAA,MAAM,aAAA,GAAqC;AAAA,IACzC,UAAA,EAAY,qCAAA;AAAA,IACZ,SAAA,EAAW;AAAA,GACb;AAGA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,uBACEF,KAAC,IAAA,EAAA,EAAK,SAAA,EAAW,GAAG,yCAAA,EAA2C,SAAS,CAAA,EAAG,KAAA,EAAO,SAAA,EAChF,QAAA,EAAA;AAAA,sBAAAL,GAAAA,CAAC,cAAW,SAAA,EAAW,EAAA,CAAG,iBAAiB,sBAAA,IAA0B,WAAW,GAC9E,QAAA,kBAAAK,IAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,EAAA;AAAA,YACT,YAAA;AAAA,YACA,yBACI,mFAAA,GACA;AAAA,WACN;AAAA,UAEA,QAAA,EAAA;AAAA,4BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,EAAA;AAAA,8BAAAL,GAAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAU,qCAAA,EAAuC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,8BAClEA,GAAAA,CAAC,eAAA,EAAA,EAAgB,SAAA,EAAU,kBAAkB,QAAA,EAAA,WAAA,EAAY;AAAA,aAAA,EAC3D,CAAA;AAAA,4BACAK,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8CAAA,EACZ,QAAA,EAAA;AAAA,cAAA,oBAAA,mBACCL,GAAAA,CAAC,qBAAA,EAAA,EAAsB,WAAA,EAAa,oBAClC,QAAA,kBAAAK,IAAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,IAAA;AAAA,kBACL,OAAA,EAAQ,SAAA;AAAA,kBACR,SAAA,EAAU,mCAAA;AAAA,kBACV,YAAA,EAAY,GAAG,kBAAkB,CAAA,oBAAA,CAAA;AAAA,kBACjC,OAAA,EAAS,oBAAA;AAAA,kBACT,IAAA,EAAK,QAAA;AAAA,kBAEL,QAAA,EAAA;AAAA,oCAAAL,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,0DAAA,EAA2D,eAAY,MAAA,EAAO,CAAA;AAAA,oCAC3FA,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,kBAAA,EAAmB;AAAA;AAAA;AAAA,iBAE9B,CAAA,GACE,IAAA;AAAA,8BACJK,IAAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,eAAe,kBAAA,EACpC,QAAA,EAAA;AAAA,gCAAAL,GAAAA;AAAA,kBAAC,aAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,IAAA;AAAA,oBACL,SAAA,EAAU,sCAAA;AAAA,oBACV,YAAA,EAAW,0BAAA;AAAA,oBAEX,QAAA,kBAAAA,IAAC,WAAA,EAAA,EAAY;AAAA;AAAA,iBACf;AAAA,gCACAA,IAAC,aAAA,EAAA,EAAc,KAAA,EAAM,OAAM,UAAA,EAAY,CAAA,EACpC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,qBACZA,GAAAA,CAAC,UAAA,EAAA,EAAyB,OAAO,CAAA,CAAE,KAAA,EAChC,YAAE,KAAA,EAAA,EADY,CAAA,CAAE,KAEnB,CACD,CAAA,EACH;AAAA,eAAA,EACF;AAAA,aAAA,EACF;AAAA;AAAA;AAAA,OACF,EACF,CAAA;AAAA,sBACAA,GAAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,aAAA,EACrB,QAAA,kBAAAA,GAAAA,CAAC,eAAA,EAAA,EAAiB,GAAG,UAAA,EAAY,UAAA,EAAY,KAAA,EAAO,CAAA,EACtD;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ;AAGA,EAAA,IAAI,YAAY,SAAA,EAAW;AACzB,IAAA,uBACEA,IAAC,IAAA,EAAA,EAAK,SAAA,EAAW,GAAG,2BAAA,EAA6B,SAAS,CAAA,EAAG,KAAA,EAAO,SAAA,EAClE,QAAA,kBAAAA,IAAC,WAAA,EAAA,EAAY,SAAA,EAAU,WAAA,EACrB,QAAA,kBAAAA,GAAAA,CAAC,eAAA,EAAA,EAAiB,GAAG,UAAA,EAAY,UAAA,EAAY,KAAA,EAAO,CAAA,EACtD,CAAA,EACF,CAAA;AAAA,EAEJ;AAGA,EAAA,uBACEA,GAAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,YAAA,EAAY,KAAA;AAAA,MACZ,SAAA,EAAW,EAAA,CAAG,2CAAA,EAA6C,SAAS,CAAA;AAAA,MACpE,KAAA,EAAO,aAAA;AAAA,MAEP,QAAA,kBAAAA,GAAAA;AAAA,QAAC,eAAA;AAAA,QAAA;AAAA,UACE,GAAG,UAAA;AAAA,UACJ,YAAA,EAAa,cAAA;AAAA,UACb;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;AAOO,SAAS,iBAAA,CAAkB;AAAA,EAChC,UAAU,EAAC;AAAA,EACX,OAAA;AAAA,EACA,cAAA,GAAiB,KAAA;AAAA,EACjB,gBAAA,GAAmB;AACrB,CAAA,EAAyF;AACvF,EAAA,MAAM,OAAuB,EAAC;AAC9B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,IAAK,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAE7E,EAAA,uBACEA,GAAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,EAAA;AAAA,MACN,WAAA,EAAY,EAAA;AAAA,MACZ,MAAA,EAAO,EAAA;AAAA,MACP,SAAS,EAAC;AAAA,MACV,OAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA;AAAA,MACA,gBAAgB,MAAM;AAAA,MAAC,CAAA;AAAA,MACvB,UAAA,EAAY,KAAA;AAAA,MACZ,cAAA;AAAA,MACA,gBAAA;AAAA,MACA,2BAAA,EAA4B;AAAA;AAAA,GAC9B;AAEJ","file":"key-metrics.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","/**\n * Card — surface component\n *\n * ── SPACING SYSTEM (do not override) ────────────────────────────────────────\n * Card owns all vertical rhythm:\n * py-4 → 16px top + 16px bottom padding on the card itself\n * gap-4 → 16px gap between CardHeader, CardContent, and CardFooter\n *\n * Rules:\n * ✗ Never add pb-X / pt-X to CardContent or CardHeader\n * ✗ Never add h-full / flex / flex-col to the Card wrapper\n * ✗ Never add flex-1 / min-h-0 to CardContent\n * ✗ Never add shrink-0 / pb-2 to CardHeader\n * ✓ For scrollable list content (Activity, Tasks): add overflow-auto only\n * ✓ For equal-height grid pairs in MixView: handle at grid cell level\n *\n * ── GLOW TREATMENT ──────────────────────────────────────────────────────────\n * Only two approved uses — see full spec in key-metrics.tsx GLOW GUIDELINE:\n * 1. AI surfaces (Insights card, Ask Leo responses) → opacity 0.12–0.16\n * 2. Hero sections (Key Metrics KPI band, onboarding) → opacity 0.18–0.24\n * Always pair with overflow-hidden on the Card.\n * Never add glow to: Tasks, Activity, Learn, Charts, nav elements.\n *\n * ── FOOTER PATTERN ──────────────────────────────────────────────────────────\n * Use CardFooter for card-level CTA actions (e.g. \"View all tasks\", \"Ask Leo\").\n * CardFooter renders with border-t + bg-muted/50 automatically.\n * Do not put primary workflow actions in CardFooter — use CardHeader CardAction.\n *\n * ── SIZE VARIANT ────────────────────────────────────────────────────────────\n * size=\"sm\" → tighter spacing (py-3, gap-3, px-3). Use inside compact grids.\n * size=\"default\" (implicit) → standard spacing described above.\n */\n\nimport * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-slot=\"card\"\n data-size={size}\n className={cn(\n \"group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\n \"font-sans text-base leading-snug font-medium group-data-[size=sm]/card:text-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-4 group-data-[size=sm]/card:px-3\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n \"flex items-center rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/card:p-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Select({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return (\n <SelectPrimitive.Group\n data-slot=\"select-group\"\n className={cn(\"scroll-my-1 p-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectValue({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\"\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit cursor-pointer items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pe-2 ps-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/15 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <i className=\"fa-light fa-chevron-down pointer-events-none size-4 text-muted-foreground\" aria-hidden=\"true\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"item-aligned\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n data-align-trigger={position === \"item-aligned\"}\n className={cn(\"relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", position ===\"popper\"&&\"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 rtl:data-[side=left]:translate-x-1 data-[side=right]:translate-x-1 rtl:data-[side=right]:-translate-x-1 data-[side=top]:-translate-y-1\", className )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n data-position={position}\n className={cn(\n \"data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)\",\n position === \"popper\" && \"\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"px-1.5 py-1 text-xs text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pe-8 ps-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_i]:pointer-events-none [&_svg]:shrink-0 [&_i]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute end-2 flex size-4 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <i className=\"fa-light fa-check pointer-events-none\" aria-hidden=\"true\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <i className=\"fa-light fa-chevron-up\" aria-hidden=\"true\"\n />\n </SelectPrimitive.ScrollUpButton>\n )\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <i className=\"fa-light fa-chevron-down\" aria-hidden=\"true\"\n />\n </SelectPrimitive.ScrollDownButton>\n )\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Separator as SeparatorPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch\",\n className,\n )}\n {...props}\n />\n )\n}\n\nexport { Separator }\n","import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 cursor-pointer items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\n outline:\n \"border-input bg-background hover:bg-interactive-hover hover:text-interactive-hover-foreground aria-expanded:bg-interactive-hover aria-expanded:text-interactive-hover-foreground dark:bg-input/15 dark:hover:bg-input/25\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-interactive-hover hover:text-interactive-hover-foreground aria-expanded:bg-interactive-hover aria-expanded:text-interactive-hover-foreground dark:hover:bg-interactive-hover-subtle\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pe-2.5 has-data-[icon=inline-start]:ps-2.5\",\n xs: \"h-6 gap-1 px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-8 gap-1 px-3 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2 [&_svg:not([class*='size-'])]:size-3.5\",\n lg: \"h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pe-3.5 has-data-[icon=inline-start]:ps-3.5\",\n icon: \"size-9\",\n \"icon-xs\":\n \"size-6 in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-8 in-data-[slot=button-group]:rounded-lg\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nconst Button = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }\n>(({ className, variant = \"default\", size = \"default\", asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n ref={ref}\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n )\n})\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n}\n\nfunction TooltipTrigger({\n className,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return (\n <TooltipPrimitive.Trigger\n data-slot=\"tooltip-trigger\"\n suppressHydrationWarning\n className={cn(\"cursor-pointer\", className)}\n {...props}\n />\n )\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }\n","\"use client\"\n\n/**\n * KeyMetricsProvider — host-app injection point for the design-system\n * `KeyMetrics` component.\n *\n * `KeyMetrics` itself ships as a pure primitive: it knows how to render\n * a KPI strip, an insight rail, and a default insight CTA, but it does\n * NOT know anything about the host app's AI assistant, command palette,\n * or keyboard-shortcut registry.\n *\n * Consumers (e.g. `apps/web`) mount a `KeyMetricsProvider` near the root\n * of the app and supply two optional injection points:\n *\n * - `defaultInsightAction` — fired when the user clicks the default\n * \"Ask Leo about these metrics\" button in the card-variant header,\n * and the default insight CTA when an individual `MetricInsight` did\n * not supply its own `onAction`. When omitted, the default button is\n * hidden entirely so the primitive stays useful in apps without an\n * AI assistant.\n *\n * - `shortcutHint` — inline React node rendered inside the tooltip\n * alongside the action label (typically a keyboard chord such as\n * `<Kbd>⌘⌥K</Kbd>`). When omitted, the tooltip simply shows the\n * label.\n *\n * - `defaultActionLabel` — visible label + accessible name for the\n * default action button. Defaults to \"Ask Leo\" so the existing\n * Exxat-DS layout reads identically without any consumer changes.\n *\n * This is the SAME injection shape used by Adobe Spectrum\n * (`Provider`-based service injection) and Material UI (`Theme`\n * context). It lets the design-system package ship product patterns\n * without taking on a hard dependency on the host app's AI surface.\n */\n\nimport * as React from \"react\"\n\nexport interface KeyMetricsContextValue {\n /** Click handler for the default \"Ask Leo about these metrics\" CTA. */\n defaultInsightAction?: () => void\n /** Inline kbd chord (or any node) rendered next to the action label inside the tooltip. */\n shortcutHint?: React.ReactNode\n /** Label + aria-label for the default insight action button. Defaults to \"Ask Leo\". */\n defaultActionLabel?: string\n}\n\nconst KeyMetricsContext = React.createContext<KeyMetricsContextValue>({})\n\n/** Read the active `KeyMetricsProvider` value. Returns an empty object if no provider is mounted. */\nexport function useKeyMetricsContext(): KeyMetricsContextValue {\n return React.useContext(KeyMetricsContext)\n}\n\nexport function KeyMetricsProvider({\n value,\n children,\n}: {\n value: KeyMetricsContextValue\n children: React.ReactNode\n}) {\n // Memoize the wrapper so consumers passing fresh object identities\n // (common in client components) do not invalidate every descendant\n // that reads the context.\n const memo = React.useMemo<KeyMetricsContextValue>(\n () => ({\n defaultInsightAction: value.defaultInsightAction,\n shortcutHint: value.shortcutHint,\n defaultActionLabel: value.defaultActionLabel,\n }),\n [value.defaultInsightAction, value.shortcutHint, value.defaultActionLabel],\n )\n return (\n <KeyMetricsContext.Provider value={memo}>\n {children}\n </KeyMetricsContext.Provider>\n )\n}\n","\"use client\"\n\n/**\n * KeyMetrics — WCAG 2.1 AA reusable KPI panel\n *\n * Variants:\n * \"card\" (default) — shadcn Card wrapper with brand gradient fill\n * \"flat\" — full-width soft tint band (brand-tint → background) + bottom glow, no card chrome\n *\n * AA checklist:\n * ✓ Trend text never relies on colour alone — icon + label (WCAG 1.4.1)\n * ✓ `trend` matches signed change; `trendPolarity` flips sentiment when “up” is bad (see `docs/kpi-trend-pattern.md`)\n * ✓ Trend icons have aria-hidden; chip `aria-label` uses `metricTrendAriaQualifier` (1.1.1)\n * ✓ Select has accessible label via aria-label (4.1.2)\n * ✓ Insight action button has descriptive text (4.1.2)\n * ✓ Decorative dividers are aria-hidden (1.1.1)\n * ✓ Contrast: value text foreground ≥ 17:1, trend colours ≥ 4.5:1 (1.4.3)\n */\n\nimport * as React from \"react\"\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"./card\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"./select\"\nimport { Separator } from \"./separator\"\nimport { Button } from \"./button\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"./tooltip\"\nimport { cn } from \"../../lib/utils\"\nimport { useKeyMetricsContext } from \"./key-metrics-context\"\n\nexport {\n KeyMetricsProvider,\n useKeyMetricsContext,\n type KeyMetricsContextValue,\n} from \"./key-metrics-context\"\n\n/**\n * Tooltip around the default insight CTA. Renders the shortcut hint\n * injected by `KeyMetricsProvider` (typically `⌘⌥K` for Ask Leo) when\n * the CTA still uses the default action label — i.e. the consumer did\n * NOT override `actionLabel` on the individual `MetricInsight`. Any\n * custom `actionLabel` (\"Open ticket\", \"Acknowledge\", …) suppresses\n * the shortcut hint since it no longer maps to the default chord.\n */\nfunction InsightDefaultTooltip({\n actionLabel,\n children,\n}: {\n actionLabel?: string\n children: React.ReactNode\n}) {\n const { shortcutHint, defaultActionLabel = \"Ask Leo\" } = useKeyMetricsContext()\n const label = actionLabel ?? defaultActionLabel\n const showShortcut =\n !!shortcutHint && (!actionLabel || actionLabel === defaultActionLabel)\n if (!showShortcut) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>{children}</TooltipTrigger>\n <TooltipContent side=\"top\">{label}</TooltipContent>\n </Tooltip>\n )\n }\n return (\n <Tooltip>\n <TooltipTrigger asChild>{children}</TooltipTrigger>\n <TooltipContent side=\"top\" className=\"flex flex-wrap items-center gap-1.5\">\n <span>{label}</span>\n {shortcutHint}\n </TooltipContent>\n </Tooltip>\n )\n}\n\n/* ── Types ────────────────────────────────────────────────────────────────── */\n\n/**\n * Whether an **up** arrow should read as “good news” for tinting and assistive text.\n * - **`higher_is_better`** (default) — revenue, pass rate, approved count: up = favorable.\n * - **`lower_is_better`** — defects, overdue, **low PBI / quality flags**: more flags + up arrow = unfavorable.\n * - **`informational`** — volume or mix only; keep arrows **muted** (direction without value judgment).\n */\nexport type MetricTrendPolarity = \"higher_is_better\" | \"lower_is_better\" | \"informational\"\n\nexport type MetricTrendTone = \"positive\" | \"negative\" | \"muted\"\n\n/** Maps `trend` + polarity to semantic tone for colours (arrow direction still follows `trend`). */\nexport function metricTrendTone(\n trend: \"up\" | \"down\" | \"neutral\",\n polarity: MetricTrendPolarity = \"higher_is_better\",\n): MetricTrendTone {\n if (trend === \"neutral\") return \"muted\"\n if (polarity === \"informational\") return \"muted\"\n if (polarity === \"higher_is_better\") {\n return trend === \"up\" ? \"positive\" : \"negative\"\n }\n return trend === \"up\" ? \"negative\" : \"positive\"\n}\n\n/** Short clause for `aria-label` on the trend chip (paired with the delta string). */\nexport function metricTrendAriaQualifier(\n trend: \"up\" | \"down\" | \"neutral\",\n polarity: MetricTrendPolarity = \"higher_is_better\",\n): string {\n if (trend === \"neutral\") return \"no net change\"\n if (polarity === \"informational\") {\n return trend === \"up\" ? \"increased\" : \"decreased\"\n }\n if (polarity === \"higher_is_better\") {\n return trend === \"up\" ? \"increased, favorable\" : \"decreased, unfavorable\"\n }\n return trend === \"up\" ? \"increased, unfavorable\" : \"decreased, favorable\"\n}\n\nexport interface MetricItem {\n /** Unique identifier for React keying */\n id: string\n /** Short label shown above the value */\n label: string\n /** Displayed value — e.g. \"23\", \"98%\", \"1,250\" */\n value: string | number\n /**\n * Change **count** for the trend chip — e.g. `\"+5\"`, `\"-3\"`, `\"+12%\"`.\n *\n * Pass an **empty string** (or `0`) when there is no comparison delta to show.\n * In that case the **trend chip is hidden entirely** (the previous `—` placeholder\n * is dropped) — see `MetricCell`. Put contextual prose like\n * `\"left + right\"` / `\"vs last week\"` in `description`, **never** here.\n */\n delta: string | number\n /**\n * Visual trend direction (arrow follows the signed change in the underlying metric).\n * `\"neutral\"` paired with an empty `delta` suppresses the chip — use `description`\n * for any caption you want to show below the value instead.\n */\n trend: \"up\" | \"down\" | \"neutral\"\n /**\n * Optional short caption rendered **below** the value + trend row (muted, small).\n * Use for **what** the number means or **how** it breaks down\n * (e.g. `\"left + right\"`, `\"vs last week\"`, `\"across 4 sites\"`) — NOT for delta counts.\n */\n description?: string\n /**\n * How to **tint** the trend chip. Omit = **`higher_is_better`** (legacy behaviour).\n * Arrows always match `trend`; sentiment colours flip for **`lower_is_better`**.\n */\n trendPolarity?: MetricTrendPolarity\n /** Makes the cell a link */\n href?: string\n /** Makes the cell a button */\n onClick?: () => void\n /**\n * \"hero\" — primary KPI (e.g. total count): larger value, same structure as siblings.\n * \"default\" — standard KPI strip cell.\n */\n metricVariant?: \"default\" | \"hero\"\n}\n\nexport interface MetricInsight {\n /** Optional single line for custom copy; rail prefers `title` + `description` when both are set */\n statement?: string\n /** Card headline */\n title: string\n /** Supporting body copy */\n description?: string\n /** Optional deep-link for the ↗ button */\n href?: string\n /** CTA label — defaults to \"Ask Leo\" */\n actionLabel?: string\n /** Font Awesome class for the CTA icon — defaults to fa-wand-magic-sparkles */\n actionIcon?: string\n /** Callback for the CTA button */\n onAction?: () => void\n /** Severity determines the badge colour (default: warning) */\n severity?: \"warning\" | \"info\" | \"error\"\n}\n\nexport interface PeriodOption {\n value: string\n label: string\n}\n\nexport interface KeyMetricsProps {\n /**\n * \"card\" — shadcn Card with brand gradient (default)\n * \"flat\" — full-width gradient band, no card chrome\n */\n variant?: \"card\" | \"flat\" | \"compact\"\n /** Panel title */\n title?: string\n /** Subtitle / description below title */\n description?: string\n /** Array of KPI items — by default split into rows of 3 */\n metrics: MetricItem[]\n /** When true, all metrics share one horizontal row (md+ and compact mobile grid) */\n metricsSingleRow?: boolean\n /**\n * When true with `metricsSingleRow`, use a 2-column KPI grid so half-width dashboard cards\n * fit 1–4 KPIs without horizontal overflow (pair rows on md+; 2-col grid on small screens).\n * The insight rail (if any) stacks below the KPI grid instead of sitting beside it on md+.\n */\n metricsHalfWidthLayout?: boolean\n /** Optional insight card — see `insightFullWidth` */\n insight?: MetricInsight\n /**\n * When true, the insight sits on its own full-width row under the metrics (not a narrow side rail).\n */\n insightFullWidth?: boolean\n /** Comparison-period options for the Select */\n periods?: PeriodOption[]\n /** Initially-selected period value */\n defaultPeriod?: string\n /** Called with the new period value when the Select changes */\n onPeriodChange?: (period: string) => void\n /** When false, hides the title/description/period-selector header row (default: true) */\n showHeader?: boolean\n /**\n * Tighter insight card: one short title + line of body, no vertical filler;\n * aligns visually with a single-row KPI band.\n */\n insightCompact?: boolean\n className?: string\n}\n\n/**\n * KPI grid column step patterns — Tailwind v4 container-query classes.\n *\n * We deliberately AVOID `repeat(auto-fit, minmax(...))` here because it\n * produces awkward \"N + leftover\" layouts at intermediate widths (e.g. 3\n * tiles in row 1 + 1 lonely tile in row 2 for a 4-KPI strip). Instead we\n * step the column count through values that evenly divide the row size:\n * 1 → 2 → 4 for a 4-KPI strip (3 is skipped on purpose).\n *\n * The breakpoints are container-query based (`@[Xrem]:…`) so they react to\n * the metrics strip's OWN width, not the viewport — that's what makes the\n * 2×2 fallback kick in when the primary sidebar + secondary panel are\n * both open and the strip column is ~360 px wide, even on a 1280 px display.\n *\n * `metricsHalfWidthLayout` = strip shares its row with the insight rail\n * (3fr / 2fr split). Tighter breakpoints because available width is ~60%\n * of the section.\n */\n/**\n * Flat KPI hairlines — cell borders only (no grid gap fill / no surface).\n * Four tiles: default 4-across verticals; 2×2 hairlines only when @container is narrow.\n */\nfunction flatMetricsHairlineClass(\n itemCount: number,\n metricsHalfWidthLayout: boolean,\n): string {\n if (itemCount <= 1) return \"gap-0\"\n\n const childBorder = \"[&>*]:border-[color:var(--key-metrics-flat-divider)]\"\n\n if (itemCount === 2) {\n return cn(\"gap-0\", childBorder, \"[&>*:first-child]:border-e\")\n }\n\n if (itemCount === 4) {\n const narrow2x2 = metricsHalfWidthLayout\n ? \"@[max-width:25.99rem]\"\n : \"@[max-width:29.99rem]\"\n return cn(\n \"gap-0\",\n childBorder,\n /* Wide strip (matches `@[30rem]:grid-cols-4`) — verticals between all tiles, no horizontal */\n \"[&>*:not(:last-child)]:border-e\",\n /* Narrow strip (`@[18rem]`–`@[30rem]` 2×2) */\n `${narrow2x2}:[&>*:not(:last-child)]:border-e-0`,\n `${narrow2x2}:[&>*:nth-child(odd)]:border-e`,\n `${narrow2x2}:[&>*:not(:nth-last-child(-n+2))]:border-b`,\n )\n }\n\n return cn(\"gap-0\", childBorder, \"[&>*:not(:last-child)]:border-e\")\n}\n\nfunction metricsRowColumnsClass(rowLength: number, metricsHalfWidthLayout: boolean): string {\n const half = metricsHalfWidthLayout\n switch (rowLength) {\n case 1:\n return \"grid-cols-1\"\n case 2:\n return half\n ? \"grid-cols-1 @[14rem]:grid-cols-2\"\n : \"grid-cols-1 @[18rem]:grid-cols-2\"\n case 3:\n // 3 tiles divide evenly already — step 1 → 3.\n return half\n ? \"grid-cols-1 @[18rem]:grid-cols-3\"\n : \"grid-cols-1 @[24rem]:grid-cols-3\"\n case 4:\n // Step 1 → 2 (2×2 grid) → 4. Skip 3 — that's the awkward 3+1 layout.\n // Aggressive 4-col thresholds so the strip fits all four tiles even\n // when the primary sidebar + secondary panel + insight rail are all\n // expanded (typical library layout puts the KPI grid at ~27rem).\n return half\n ? \"grid-cols-1 @[14rem]:grid-cols-2 @[26rem]:grid-cols-4\"\n : \"grid-cols-1 @[18rem]:grid-cols-2 @[30rem]:grid-cols-4\"\n default:\n // 5+ KPIs (`exxat-kpi-max-four` caps the strip at 4, but key-metrics\n // is a generic primitive — fall back to a sensible step). 1 → 2 → 3 → 6.\n return half\n ? \"grid-cols-1 @[14rem]:grid-cols-2 @[26rem]:grid-cols-3 @[40rem]:grid-cols-6\"\n : \"grid-cols-1 @[18rem]:grid-cols-2 @[30rem]:grid-cols-3 @[56rem]:grid-cols-6\"\n }\n}\n\n/* ── Default data ─────────────────────────────────────────────────────────── */\n\nconst DEFAULT_PERIODS: PeriodOption[] = [\n { value: \"week\", label: \"vs last week\" },\n { value: \"month\", label: \"vs last month\" },\n { value: \"quarter\", label: \"vs last quarter\" },\n { value: \"year\", label: \"vs last year\" },\n]\n\n/* ── Sub-components ───────────────────────────────────────────────────────── */\n\n/** Single KPI cell inside the metrics grid */\nconst MetricCell = React.memo(function MetricCell({\n label,\n value,\n delta,\n trend,\n trendPolarity = \"higher_is_better\",\n description,\n href,\n onClick,\n metricVariant = \"default\",\n dense = false,\n edgeGutter = true,\n}: Omit<MetricItem, \"id\"> & { dense?: boolean; edgeGutter?: boolean }) {\n const isUp = trend === \"up\"\n const isDown = trend === \"down\"\n const tone = metricTrendTone(trend, trendPolarity)\n const isInteractive = !!(href || onClick)\n const isHero = metricVariant === \"hero\"\n\n // Hide the trend chip entirely when there's no direction *and* no count to\n // surface. This avoids the noisy `—` placeholder for purely informational\n // metrics — see `docs/kpi-trend-pattern.md`.\n const deltaText = typeof delta === \"number\"\n ? (delta === 0 ? \"\" : String(delta))\n : String(delta ?? \"\").trim()\n const showTrendChip = isUp || isDown || deltaText.length > 0\n\n const inner = (\n <>\n {/* Label row — min-height = 2 lines so values align when some titles wrap */}\n <div\n className={cn(\n \"grid grid-cols-[minmax(0,1fr)_auto] items-start gap-x-2 gap-y-0.5\",\n dense ? \"min-h-[2.125rem]\" : \"min-h-[2.625rem]\",\n )}\n >\n <p\n className={cn(\n \"min-w-0 text-muted-foreground leading-snug wrap-break-word\",\n dense ? \"text-xs\" : \"text-sm\",\n isHero && \"font-medium\",\n )}\n >\n {label}\n </p>\n {isInteractive ? (\n <span className=\"mt-0.5 inline-flex shrink-0\" aria-hidden=\"true\">\n <i className=\"fa-light fa-arrow-right text-xs text-foreground/70 transition-colors duration-150 group-hover:text-interactive-hover-foreground sm:group-hover:translate-x-0.5\" />\n </span>\n ) : null}\n </div>\n\n {/* Value + trend badge */}\n <div className=\"flex items-baseline gap-2 flex-wrap\">\n <span\n className={cn(\n \"font-bold tabular-nums leading-none text-foreground\",\n dense\n ? isHero\n ? \"text-lg sm:text-xl\"\n : \"text-base sm:text-lg\"\n : isHero\n ? \"text-2xl sm:text-[1.625rem]\"\n : \"text-xl sm:text-2xl\",\n )}\n >\n {value}\n </span>\n\n {/* Trend chip — icon + count, never colour-only (WCAG 1.4.1).\n Suppressed when both `trend === \"neutral\"` and `delta` is empty\n (see `showTrendChip` above) so informational KPIs render cleanly. */}\n {showTrendChip && (\n <span\n className={cn(\n \"inline-flex items-center gap-1 font-medium leading-none\",\n dense ? \"text-xs sm:text-xs\" : \"text-xs sm:text-sm\",\n tone === \"positive\" && \"text-chart-2\",\n tone === \"negative\" && \"text-destructive\",\n tone === \"muted\" && \"text-muted-foreground\",\n )}\n aria-label={`${metricTrendAriaQualifier(trend, trendPolarity)} ${deltaText}`.trim()}\n >\n {isUp && <i className=\"fa-light fa-arrow-trend-up text-[0.8rem]\" aria-hidden=\"true\" />}\n {isDown && <i className=\"fa-light fa-arrow-trend-down text-[0.8rem]\" aria-hidden=\"true\" />}\n {!isUp && !isDown && deltaText.length > 0 && (\n <i className=\"fa-light fa-minus text-[0.8rem]\" aria-hidden=\"true\" />\n )}\n {deltaText.length > 0 && <span>{deltaText}</span>}\n </span>\n )}\n </div>\n\n {/* Caption — below the value row. Use for what the number means or how\n it breaks down (e.g. \"left + right\", \"vs last week\"). Never the delta. */}\n {description ? (\n <p\n className={cn(\n \"min-w-0 text-muted-foreground leading-snug wrap-break-word\",\n dense ? \"text-[11px]\" : \"text-xs\",\n )}\n >\n {description}\n </p>\n ) : null}\n </>\n )\n\n const sharedClass = cn(\n \"group flex min-w-0 flex-col gap-2 text-start outline-none\",\n edgeGutter && \"first:ps-0 last:pe-0\",\n dense ? \"gap-1.5 px-2 py-2 sm:px-3 sm:py-3\" : \"gap-2 px-3 py-3 sm:px-5 sm:py-4\",\n isHero && \"gap-2.5\",\n isInteractive && [\n \"cursor-pointer transition-colors duration-150\",\n \"hover:bg-foreground/5\",\n \"focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\",\n ]\n )\n\n if (href) {\n return (\n <a href={href} className={sharedClass} aria-label={`${label}: ${value}`}>\n {inner}\n </a>\n )\n }\n\n if (onClick) {\n return (\n <button type=\"button\" onClick={onClick} className={sharedClass} aria-label={`${label}: ${value}`}>\n {inner}\n </button>\n )\n }\n\n return <div className={sharedClass}>{inner}</div>\n})\n\n/** Body line for rail: `description`, else optional `statement` */\nfunction insightRailBody(insight: MetricInsight): string {\n const d = insight.description?.trim()\n if (d) return d\n return insight.statement?.trim() ?? \"\"\n}\n\n/**\n * Rail insight: severity badge + title + description + optional ↗, Ask Leo (no rule between copy and action).\n */\nfunction InsightRailStatementAction({\n insight,\n compact,\n}: {\n insight: MetricInsight\n compact: boolean\n}) {\n const badgeSize = compact ? \"sm\" : \"default\"\n const surface = compact\n ? \"border border-border/50 bg-gradient-to-b from-muted/35 to-card\"\n : \"bg-card\"\n const body = insightRailBody(insight)\n\n return (\n <Card\n role=\"region\"\n aria-label=\"Insight\"\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-hidden rounded-lg border-0 p-0 shadow-none ring-1 ring-foreground/8\",\n surface\n )}\n >\n {/* flex-1 + mt-auto on the CTA: copy stays top-aligned when the rail stretches to KPI height */}\n <div className=\"flex min-h-0 flex-1 flex-col px-3 py-3 sm:px-4 sm:py-4\">\n <div className=\"flex items-start gap-2.5\">\n <InsightBadge severity={insight.severity} size={badgeSize} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold leading-snug text-foreground\">{insight.title}</p>\n {body ? (\n <p className=\"mt-1 text-sm leading-snug text-muted-foreground\">{body}</p>\n ) : null}\n </div>\n {insight.href && (\n <a\n href={insight.href}\n className=\"mt-0.5 shrink-0 text-muted-foreground transition-colors hover:text-interactive-hover-foreground focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-ring\"\n aria-label={`Open ${insight.title} — details`}\n >\n <i className=\"fa-light fa-arrow-up-right text-xs\" aria-hidden=\"true\" />\n </a>\n )}\n </div>\n\n <div className=\"mt-auto flex shrink-0 justify-end pt-3\">\n <InsightDefaultTooltip actionLabel={insight.actionLabel}>\n <Button\n variant={compact ? \"outline\" : \"ghost\"}\n size=\"sm\"\n className={cn(\n \"h-8 w-full gap-1.5 text-xs sm:w-auto\",\n compact\n ? \"border-border/60 bg-background px-3 text-foreground hover:bg-background\"\n : \"px-3 text-muted-foreground hover:text-interactive-hover-foreground\"\n )}\n onClick={insight.onAction}\n aria-label={insight.actionLabel ?? \"Ask Leo\"}\n >\n <i\n className={\n insight.actionIcon\n ? `fa-light ${insight.actionIcon} text-xs`\n : \"fa-duotone fa-solid fa-star-christmas text-xs text-brand\"\n }\n aria-hidden=\"true\"\n />\n {insight.actionLabel ?? \"Ask Leo\"}\n </Button>\n </InsightDefaultTooltip>\n </div>\n </div>\n </Card>\n )\n}\n\n/** Severity icon badge for the insight card */\n\nfunction InsightBadge({\n severity = \"warning\",\n size = \"default\",\n}: {\n severity?: MetricInsight[\"severity\"]\n size?: \"default\" | \"sm\"\n}) {\n const styles = {\n warning: {\n bg: \"bg-[var(--insight-severity-warning-bg)]\",\n icon: \"fa-circle-exclamation\",\n color: \"text-[var(--insight-severity-warning-fg)]\",\n },\n info: {\n bg: \"bg-[var(--insight-severity-info-bg)]\",\n icon: \"fa-circle-info\",\n color: \"text-[var(--insight-severity-info-fg)]\",\n },\n error: { bg: \"bg-destructive/15\", icon: \"fa-circle-xmark\", color: \"text-destructive\" },\n }[severity]\n\n return (\n <span\n className={cn(\n \"inline-flex shrink-0 items-center justify-center rounded-full\",\n size === \"sm\" ? \"h-6 w-6 text-xs\" : \"h-7 w-7 text-sm\",\n styles.bg,\n styles.color\n )}\n aria-hidden=\"true\"\n >\n <i className={`fa-light ${styles.icon}`} />\n </span>\n )\n}\n\n/* ── Shared inner content ─────────────────────────────────────────────────── */\n\ninterface InnerProps {\n title: string\n description: string\n period: string\n periods: PeriodOption[]\n metrics: MetricItem[]\n rows: MetricItem[][]\n insight?: MetricInsight\n onPeriodChange: (v: string) => void\n /** Extra padding class injected by flat variant */\n innerPadding?: string\n /** When false, the header (title/description/period select) is hidden */\n showHeader?: boolean\n insightCompact?: boolean\n insightFullWidth?: boolean\n metricsSingleRow?: boolean\n /** Tighter KPI cells + 2-col mobile grid (half-width dashboard card). */\n metricsHalfWidthLayout?: boolean\n /** Opaque fill behind each KPI cell when using hairline grid gaps (below `lg`). */\n metricsCellSurfaceClassName?: string\n /** Flat list-page band: softer dividers + tinted cells on a lavender-tinted surface */\n surfaceVariant?: \"default\" | \"flat\"\n}\n\nfunction KeyMetricsInner({\n title,\n description,\n period,\n periods,\n metrics,\n rows,\n insight,\n onPeriodChange,\n innerPadding = \"\",\n showHeader = true,\n insightCompact = false,\n insightFullWidth = false,\n metricsSingleRow = false,\n metricsHalfWidthLayout = false,\n metricsCellSurfaceClassName = \"bg-background\",\n surfaceVariant = \"default\",\n}: InnerProps) {\n const isFlatBand = surfaceVariant === \"flat\"\n const metricsGridClassName = isFlatBand\n ? flatMetricsHairlineClass(metrics.length, metricsHalfWidthLayout)\n : \"gap-px bg-border\"\n /** Side-by-side KPI + insight rail (md+). Disabled for half-width dashboard cards — insight stacks below. */\n const insightSideBySide = insight && !insightFullWidth && !metricsHalfWidthLayout\n const stackedRailInsight = insight && !insightFullWidth && metricsHalfWidthLayout\n\n return (\n <div data-slot=\"key-metrics\" className=\"contents\">\n {/* ── Header ──────────────────────────────────────────────────── */}\n {showHeader && (\n <div className={cn(\n \"flex flex-col gap-2 pb-3\",\n \"sm:flex-row sm:items-center sm:justify-between sm:gap-4\",\n innerPadding\n )}>\n <div>\n <p className=\"text-base font-semibold text-foreground leading-tight\">{title}</p>\n <p className=\"mt-0.5 text-sm text-muted-foreground\">{description}</p>\n </div>\n\n {/* Period selector — align=\"end\" keeps dropdown flush-right */}\n <Select value={period} onValueChange={onPeriodChange}>\n <SelectTrigger\n className=\"h-8 w-full sm:w-auto sm:min-w-[9rem] shrink-0 text-sm\"\n aria-label=\"Select comparison period\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\" sideOffset={4}>\n {periods.map((p) => (\n <SelectItem key={p.value} value={p.value}>\n {p.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n\n {/* ── Body: metrics grid + optional insight ───────────────────── */}\n <div\n className={cn(\n \"flex flex-col gap-0\",\n /* 60% KPIs / 40% insight (3fr:2fr); lg+ only so phones/tablets stack KPIs + insight */\n insightSideBySide &&\n \"lg:grid lg:grid-cols-[minmax(0,3fr)_minmax(13rem,2fr)] lg:items-stretch lg:gap-x-6 lg:gap-y-0\",\n innerPadding\n )}\n >\n\n {/* Metrics section — self-start so KPI cells don’t stretch when the insight column is taller */}\n <div\n className={cn(\n \"min-w-0 lg:flex lg:min-h-0 lg:flex-col\",\n !insightSideBySide && \"w-full\",\n insightSideBySide && \"lg:self-start\"\n )}\n >\n {/*\n Phone (<md): one column. Tablet (md–lg): 2-column grid (e.g. 2×2 for four KPIs).\n Hairline separators use gap-px + opaque cell surfaces (divide-* breaks for 2-col order).\n Half-width dashboard cards keep divide-x + optional template columns.\n */}\n {metricsHalfWidthLayout ? (\n <div\n className={cn(\n \"@container/metrics-strip grid lg:hidden\",\n metricsSingleRow\n ? metricsRowColumnsClass(metrics.length, /* half */ true)\n : \"grid-cols-2\",\n metricsGridClassName,\n )}\n >\n {metrics.map((m) => (\n <div key={m.id} className={cn(\"min-w-0\", metricsCellSurfaceClassName)}>\n <MetricCell {...m} dense edgeGutter={false} />\n </div>\n ))}\n </div>\n ) : (\n <div\n className={cn(\n \"@container/metrics-strip grid lg:hidden\",\n metricsRowColumnsClass(metrics.length, /* half */ false),\n metricsGridClassName,\n )}\n >\n {metrics.map((m) => (\n <div key={m.id} className={cn(\"min-w-0\", metricsCellSurfaceClassName)}>\n <MetricCell {...m} dense={false} edgeGutter={false} />\n </div>\n ))}\n </div>\n )}\n\n {/*\n lg+: row-by-row container-queried grid. Uses a `gap-px + bg` hairline\n instead of `divide-x` so dividers render correctly when the row wraps\n from 4-across to a 2×2 grid (the awkward 3+1 layout is skipped — see\n `metricsRowColumnsClass`).\n */}\n <div className=\"@container/metrics-strip hidden lg:block\">\n {rows.map((row, rowIdx) => (\n <React.Fragment key={rowIdx}>\n {rowIdx > 0 && !isFlatBand && (\n <Separator aria-hidden=\"true\" className=\"my-1\" />\n )}\n <div\n className={cn(\n \"grid\",\n metricsRowColumnsClass(row.length, metricsHalfWidthLayout),\n isFlatBand\n ? flatMetricsHairlineClass(row.length, metricsHalfWidthLayout)\n : metricsGridClassName,\n )}\n >\n {row.map((m) => (\n <div key={m.id} className={cn(\"min-w-0\", metricsCellSurfaceClassName)}>\n <MetricCell {...m} dense={metricsHalfWidthLayout} edgeGutter={false} />\n </div>\n ))}\n </div>\n </React.Fragment>\n ))}\n </div>\n </div>\n\n {/* Insight card — only rendered when data provided */}\n {insight && (\n <>\n {insightFullWidth ? (\n <Separator\n aria-hidden=\"true\"\n className={cn(\"my-4 w-full\", isFlatBand && \"bg-foreground/[0.06]\")}\n />\n ) : stackedRailInsight ? (\n <Separator\n aria-hidden=\"true\"\n className={cn(\"my-4 w-full\", isFlatBand && \"bg-foreground/[0.06]\")}\n />\n ) : (\n <Separator\n aria-hidden=\"true\"\n className={cn(\"my-3 lg:hidden\", isFlatBand && \"bg-foreground/[0.055]\")}\n />\n )}\n\n <div\n className={cn(\n \"flex min-h-0 min-w-0 w-full flex-col\",\n /* Divider + padding replace vertical Separator so grid stays 2 columns */\n insightSideBySide &&\n !insightFullWidth &&\n cn(\n \"lg:h-full lg:ps-6\",\n /* Flat band: insight card ring is the divider — skip `border-l` (double line). */\n !isFlatBand && \"lg:border-s lg:border-border\",\n )\n )}\n >\n {insight && !insightFullWidth ? (\n <InsightRailStatementAction insight={insight} compact={insightCompact} />\n ) : (\n <Card\n role=\"region\"\n aria-label=\"Insight\"\n className={cn(\n \"overflow-hidden rounded-lg p-0 ring-1 ring-foreground/8 shadow-none\",\n \"flex min-h-0 flex-col bg-muted/25\"\n )}\n >\n {insightCompact ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-4 p-4 md:flex-row md:items-center md:justify-between md:gap-8 md:p-5\">\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n <div className=\"flex items-start gap-2.5\">\n <InsightBadge severity={insight.severity} size=\"sm\" />\n <div className=\"flex min-w-0 flex-1 items-start justify-between gap-2\">\n <p className=\"text-base font-semibold leading-tight text-foreground\">\n {insight.title}\n </p>\n {insight.href && (\n <a\n href={insight.href}\n className=\"shrink-0 text-muted-foreground transition-colors hover:text-interactive-hover-foreground focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-ring\"\n aria-label={`Open ${insight.title} — details`}\n >\n <i className=\"fa-light fa-arrow-up-right text-xs\" aria-hidden=\"true\" />\n </a>\n )}\n </div>\n </div>\n {insight.description ? (\n <p className=\"text-sm leading-relaxed text-muted-foreground\">\n {insight.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex w-full shrink-0 md:w-auto\">\n <InsightDefaultTooltip actionLabel={insight.actionLabel}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full gap-1.5 px-4 text-xs text-muted-foreground hover:text-interactive-hover-foreground md:min-w-[8.5rem]\"\n onClick={insight.onAction}\n aria-label={insight.actionLabel ?? \"Ask Leo\"}\n >\n <i\n className={insight.actionIcon ? `fa-light ${insight.actionIcon} text-xs` : \"fa-duotone fa-solid fa-star-christmas text-xs text-brand\"}\n aria-hidden=\"true\"\n />\n {insight.actionLabel ?? \"Ask Leo\"}\n </Button>\n </InsightDefaultTooltip>\n </div>\n </div>\n ) : (\n <div className=\"flex min-h-0 flex-1 flex-col gap-4 p-4 md:flex-row md:items-center md:justify-between md:gap-8 md:p-5\">\n <div className=\"flex min-w-0 flex-1 flex-col gap-3\">\n <div className=\"flex items-start gap-3\">\n <InsightBadge severity={insight.severity} />\n <div className=\"flex min-w-0 flex-1 items-start justify-between gap-2\">\n <p className=\"text-base font-semibold leading-snug text-foreground\">\n {insight.title}\n </p>\n {insight.href && (\n <a\n href={insight.href}\n className=\"shrink-0 text-muted-foreground transition-colors hover:text-interactive-hover-foreground focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-ring\"\n aria-label={`Open ${insight.title} — details`}\n >\n <i className=\"fa-light fa-arrow-up-right text-xs\" aria-hidden=\"true\" />\n </a>\n )}\n </div>\n </div>\n {insight.description ? (\n <p className=\"text-sm leading-relaxed text-muted-foreground\">\n {insight.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex w-full shrink-0 md:w-auto\">\n <InsightDefaultTooltip actionLabel={insight.actionLabel}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full gap-1.5 px-4 text-xs text-muted-foreground hover:text-interactive-hover-foreground md:min-w-[8.5rem]\"\n onClick={insight.onAction}\n aria-label={insight.actionLabel ?? \"Ask Leo\"}\n >\n <i\n className={insight.actionIcon ? `fa-light ${insight.actionIcon} text-xs` : \"fa-duotone fa-solid fa-star-christmas text-xs text-brand\"}\n aria-hidden=\"true\"\n />\n {insight.actionLabel ?? \"Ask Leo\"}\n </Button>\n </InsightDefaultTooltip>\n </div>\n </div>\n )}\n </Card>\n )}\n </div>\n </>\n )}\n </div>\n </div>\n )\n}\n\nfunction chunkMetricPairs(metrics: MetricItem[]): MetricItem[][] {\n const out: MetricItem[][] = []\n for (let i = 0; i < metrics.length; i += 2) out.push(metrics.slice(i, i + 2))\n return out\n}\n\n/* ── Main component ───────────────────────────────────────────────────────── */\n\nexport function KeyMetrics({\n variant = \"card\",\n title = \"Key Metrics\",\n description = \"Overview of performance indicators\",\n metrics = [],\n insight,\n periods = DEFAULT_PERIODS,\n defaultPeriod = \"week\",\n onPeriodChange,\n showHeader = true,\n insightCompact = false,\n insightFullWidth = false,\n metricsSingleRow = false,\n metricsHalfWidthLayout = false,\n className,\n}: KeyMetricsProps) {\n const [period, setPeriod] = React.useState(defaultPeriod)\n // Pull the host app's \"default insight action\" (e.g. toggle Ask Leo\n // sidebar) and label out of `KeyMetricsProvider` instead of\n // hardcoding `useAskLeo()`. When no provider is mounted, the default\n // action button hides entirely so the strip stays useful in apps\n // without an AI assistant.\n const {\n defaultInsightAction,\n defaultActionLabel = \"Ask Leo\",\n } = useKeyMetricsContext()\n\n function handlePeriodChange(v: string) {\n setPeriod(v)\n onPeriodChange?.(v)\n }\n\n /* Split metrics into rows of 3, or paired rows when half-width + single row, else one row */\n const rows: MetricItem[][] = metricsSingleRow\n ? metrics.length\n ? metricsHalfWidthLayout\n ? chunkMetricPairs(metrics)\n : [metrics]\n : []\n : (() => {\n const out: MetricItem[][] = []\n for (let i = 0; i < metrics.length; i += 3) {\n out.push(metrics.slice(i, i + 3))\n }\n return out\n })()\n\n const metricsCellSurfaceClassName =\n variant === \"flat\"\n ? \"bg-transparent\"\n : \"bg-card dark:bg-transparent\"\n\n const innerProps: InnerProps = {\n title,\n description,\n period,\n periods,\n metrics,\n rows,\n insight,\n onPeriodChange: handlePeriodChange,\n insightCompact,\n insightFullWidth,\n metricsSingleRow,\n metricsHalfWidthLayout,\n metricsCellSurfaceClassName,\n surfaceVariant: variant === \"flat\" ? \"flat\" : \"default\",\n }\n\n /*\n * ── GLOW GUIDELINE ────────────────────────────────────────────────────────\n * The bottom-glow treatment is a deliberate design signal. Use it only for:\n *\n * 1. AI / intelligence surfaces — e.g. AI Insights, Ask Leo responses,\n * any card that surfaces machine-generated content.\n * Opacity: 0.12–0.16 (subtle; the glow should not dominate)\n *\n * 2. Designer-designated hero sections — e.g. Key Metrics (the primary\n * KPI band), onboarding completion, or any section the product team\n * explicitly wants to \"elevate\" visually.\n * Opacity: 0.18–0.24 (more pronounced; intentional focal point)\n *\n * Do NOT add glow to:\n * • Standard data/content cards (Tasks, Activity, Learn, Charts…)\n * • Navigation or shell elements\n * • Cards that already use a coloured border or badge for status\n *\n * Implementation:\n * style={{ background: \"radial-gradient(ellipse 110% 90% at 50% 100%,\n * oklch(from var(--brand-color) l c h / <opacity>) 0%, transparent 68%)\" }}\n * + className=\"overflow-hidden\" ← required to clip the gradient\n * ─────────────────────────────────────────────────────────────────────────\n */\n const glowStyle: React.CSSProperties = {\n background: \"var(--key-metrics-card-glow-radial)\",\n }\n\n /** List-page KPI band — transparent; only `--key-metrics-flat-band-radial` glow. */\n const flatBandStyle: React.CSSProperties = {\n background: \"var(--key-metrics-flat-band-radial)\",\n boxShadow: \"var(--key-metrics-flat-band-shadow)\",\n }\n\n /* ── Card variant — ChartCard-style chrome ───────────────────────────── */\n if (variant === \"card\") {\n return (\n <Card className={cn(\"shadow-xs overflow-hidden flex flex-col\", className)} style={glowStyle}>\n <CardHeader className={cn(\"shrink-0 pb-2\", metricsHalfWidthLayout && \"space-y-2\")}>\n <div\n className={cn(\n \"flex gap-2\",\n metricsHalfWidthLayout\n ? \"flex-col min-[400px]:flex-row min-[400px]:items-start min-[400px]:justify-between\"\n : \"items-start\",\n )}\n >\n <div className=\"flex-1 min-w-0\">\n <CardTitle className=\"text-sm font-semibold leading-tight\">{title}</CardTitle>\n <CardDescription className=\"text-xs mt-0.5\">{description}</CardDescription>\n </div>\n <div className=\"flex flex-wrap items-center gap-1.5 shrink-0\">\n {defaultInsightAction ? (\n <InsightDefaultTooltip actionLabel={defaultActionLabel}>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-7 shrink-0 text-xs gap-1.5 px-2\"\n aria-label={`${defaultActionLabel} about these metrics`}\n onClick={defaultInsightAction}\n type=\"button\"\n >\n <i className=\"fa-duotone fa-solid fa-star-christmas text-xs text-brand\" aria-hidden=\"true\" />\n <span>{defaultActionLabel}</span>\n </Button>\n </InsightDefaultTooltip>\n ) : null}\n <Select value={period} onValueChange={handlePeriodChange}>\n <SelectTrigger\n size=\"sm\"\n className=\"w-auto min-w-[9rem] shrink-0 text-sm\"\n aria-label=\"Select comparison period\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\" sideOffset={4}>\n {periods.map((p) => (\n <SelectItem key={p.value} value={p.value}>\n {p.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"flex-1 pb-4\">\n <KeyMetricsInner {...innerProps} showHeader={false} />\n </CardContent>\n </Card>\n )\n }\n\n /* ── Compact variant — card chrome, no header, metrics only ──────────── */\n if (variant === \"compact\") {\n return (\n <Card className={cn(\"shadow-xs overflow-hidden\", className)} style={glowStyle}>\n <CardContent className=\"py-3 px-4\">\n <KeyMetricsInner {...innerProps} showHeader={false} />\n </CardContent>\n </Card>\n )\n }\n\n /* ── Flat variant — no surface; bottom brand glow only ── */\n return (\n <section\n aria-label={title}\n className={cn(\"relative w-full overflow-hidden pt-5 pb-8\", className)}\n style={flatBandStyle}\n >\n <KeyMetricsInner\n {...innerProps}\n innerPadding=\"px-4 lg:px-6\"\n showHeader={showHeader}\n />\n </section>\n )\n}\n\n/**\n * KeyMetricsContent — renders just the metrics grid + optional insight panel.\n * No card wrapper, no header, no period selector.\n * Designed for embedding inside a ChartCard with tabOptions period tabs.\n */\nexport function KeyMetricsContent({\n metrics = [],\n insight,\n insightCompact = false,\n insightFullWidth = false,\n}: Pick<KeyMetricsProps, \"metrics\" | \"insight\" | \"insightCompact\" | \"insightFullWidth\">) {\n const rows: MetricItem[][] = []\n for (let i = 0; i < metrics.length; i += 3) rows.push(metrics.slice(i, i + 3))\n\n return (\n <KeyMetricsInner\n title=\"\"\n description=\"\"\n period=\"\"\n periods={[]}\n metrics={metrics}\n rows={rows}\n insight={insight}\n onPeriodChange={() => {}}\n showHeader={false}\n insightCompact={insightCompact}\n insightFullWidth={insightFullWidth}\n metricsCellSurfaceClassName=\"bg-card dark:bg-transparent\"\n />\n )\n}\n"]}
@@ -215,7 +215,7 @@ function TooltipContent({
215
215
  "data-slot": "tooltip-content",
216
216
  sideOffset,
217
217
  className: cn(
218
- "z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
218
+ "z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
219
219
  className
220
220
  ),
221
221
  ...props,