@steez-ui/ui 0.1.4 → 0.1.6

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 (61) hide show
  1. package/README.md +3 -3
  2. package/dist/components/AvatarStage.js.map +1 -1
  3. package/dist/components/BlinkText.js.map +1 -1
  4. package/dist/components/Button.js.map +1 -1
  5. package/dist/components/CopyButton.js.map +1 -1
  6. package/dist/components/CornerBracketCard.js.map +1 -1
  7. package/dist/components/CyberpunkCheckbox.js.map +1 -1
  8. package/dist/components/CyberpunkInput.js.map +1 -1
  9. package/dist/components/CyberpunkRadio.js.map +1 -1
  10. package/dist/components/CyberpunkSelect.js.map +1 -1
  11. package/dist/components/CyberpunkSlider.js.map +1 -1
  12. package/dist/components/CyberpunkTextarea.js.map +1 -1
  13. package/dist/components/CyberpunkTile.js.map +1 -1
  14. package/dist/components/ErrorMessage.js.map +1 -1
  15. package/dist/components/HeartbeatPulse.js.map +1 -1
  16. package/dist/components/HexagonGrid.d.ts +12 -0
  17. package/dist/components/HexagonGrid.d.ts.map +1 -0
  18. package/dist/components/HexagonGrid.js +284 -0
  19. package/dist/components/HexagonGrid.js.map +1 -0
  20. package/dist/components/HexagonGrid.module.css +14 -0
  21. package/dist/components/LoadingProgressBar.js.map +1 -1
  22. package/dist/components/MarqueeStrip.js.map +1 -1
  23. package/dist/components/PageHeader.js.map +1 -1
  24. package/dist/components/PageTemplate.js.map +1 -1
  25. package/dist/components/QuickInfoCard.d.ts +20 -0
  26. package/dist/components/QuickInfoCard.d.ts.map +1 -0
  27. package/dist/components/QuickInfoCard.js +38 -0
  28. package/dist/components/QuickInfoCard.js.map +1 -0
  29. package/dist/components/QuickInfoCard.module.css +138 -0
  30. package/dist/components/RuntimeOrbitDiagram.d.ts +19 -0
  31. package/dist/components/RuntimeOrbitDiagram.d.ts.map +1 -0
  32. package/dist/components/RuntimeOrbitDiagram.js +39 -0
  33. package/dist/components/RuntimeOrbitDiagram.js.map +1 -0
  34. package/dist/components/RuntimeOrbitDiagram.module.css +160 -0
  35. package/dist/components/Section.d.ts +9 -0
  36. package/dist/components/Section.d.ts.map +1 -0
  37. package/dist/components/Section.js +7 -0
  38. package/dist/components/Section.js.map +1 -0
  39. package/dist/components/Section.module.css +20 -0
  40. package/dist/components/SectionHeader.d.ts +10 -0
  41. package/dist/components/SectionHeader.d.ts.map +1 -0
  42. package/dist/components/SectionHeader.js +7 -0
  43. package/dist/components/SectionHeader.js.map +1 -0
  44. package/dist/components/SectionHeader.module.css +54 -0
  45. package/dist/components/SegmentedControl.js.map +1 -1
  46. package/dist/components/StatCard.d.ts +11 -0
  47. package/dist/components/StatCard.d.ts.map +1 -0
  48. package/dist/components/StatCard.js +14 -0
  49. package/dist/components/StatCard.js.map +1 -0
  50. package/dist/components/StatCard.module.css +41 -0
  51. package/dist/components/StatusMessage.js.map +1 -1
  52. package/dist/components/StrokedText.js.map +1 -1
  53. package/dist/components/TabbedPanel.js.map +1 -1
  54. package/dist/components/ThemeToggle.js.map +1 -1
  55. package/dist/components/ThemedCard.js.map +1 -1
  56. package/dist/hooks/useStableId.js.map +1 -1
  57. package/dist/index.d.ts +6 -0
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +6 -0
  60. package/dist/index.js.map +1 -1
  61. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"MarqueeStrip.js","sourceRoot":"","sources":["../../src/components/MarqueeStrip.tsx"],"names":[],"mappings":";AAEA,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAa/C,MAAM,UAAU,YAAY,CAAI,EAC9B,KAAK,EACL,UAAU,EACV,SAAS,EACT,eAAe,GAAG,EAAE,EACpB,GAAG,GAAG,QAAQ,EACd,YAAY,GAAG,KAAK,EACpB,SAAS,GAAG,EAAE,EACd,cAAc,GAAG,EAAE,EACnB,aAAa,GAAG,EAAE,EAClB,KAAK,EACL,GAAG,KAAK,EACa;IACrB,MAAM,YAAY,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG;QAClB,GAAG,KAAK;QACR,CAAC,oBAA8B,CAAC,EAAE,GAAG,eAAe,GAAG;QACvD,CAAC,eAAyB,CAAC,EACzB,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG;KACtB,CAAC;IAEzB,OAAO,CACL,cACE,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,gBAC9E,SAAS,EACrB,KAAK,EAAE,WAAW,KACd,KAAK,YAET,cAAK,SAAS,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,cAAc,EAAE,CAAC,IAAI,EAAE,YACvD,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CACjC,cAEE,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,aAAa,EAAE,CAAC,IAAI,EAAE,iBACtC,KAAK,IAAI,KAAK,CAAC,MAAM,YAEjC,UAAU,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAJlC,KAAK,CAKN,CACP,CAAC,GACE,GACF,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"MarqueeStrip.js","sourceRoot":"","sources":["../../src/components/MarqueeStrip.tsx"],"names":[],"mappings":";AAEA,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAa/C,MAAM,UAAU,YAAY,CAAI,EAC9B,KAAK,EACL,UAAU,EACV,SAAS,EACT,eAAe,GAAG,EAAE,EACpB,GAAG,GAAG,QAAQ,EACd,YAAY,GAAG,KAAK,EACpB,SAAS,GAAG,EAAE,EACd,cAAc,GAAG,EAAE,EACnB,aAAa,GAAG,EAAE,EAClB,KAAK,EACL,GAAG,KAAK,EACa;IACrB,MAAM,YAAY,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG;QAClB,GAAG,KAAK;QACR,CAAC,oBAA8B,CAAC,EAAE,GAAG,eAAe,GAAG;QACvD,CAAC,eAAyB,CAAC,EACzB,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG;KACtB,CAAC;IAEzB,OAAO,CACL,cACE,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,gBAC9E,SAAS,EACrB,KAAK,EAAE,WAAW,KACd,KAAK,YAET,cAAK,SAAS,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,cAAc,EAAE,CAAC,IAAI,EAAE,YACvD,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CACjC,cAEE,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,aAAa,EAAE,CAAC,IAAI,EAAE,iBACtC,KAAK,IAAI,KAAK,CAAC,MAAM,YAEjC,UAAU,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAJlC,KAAK,CAKN,CACP,CAAC,GACE,GACF,CACP,CAAC;AACJ,CAAC","sourcesContent":["import React from \"react\";\n\nimport styles from \"./MarqueeStrip.module.css\";\n\nexport interface MarqueeStripProps<T> extends React.HTMLAttributes<HTMLDivElement> {\n items: readonly T[];\n renderItem: (item: T, index: number) => React.ReactNode;\n ariaLabel?: string;\n durationSeconds?: number;\n gap?: number | string;\n pauseOnHover?: boolean;\n trackClassName?: string;\n itemClassName?: string;\n}\n\nexport function MarqueeStrip<T>({\n items,\n renderItem,\n ariaLabel,\n durationSeconds = 24,\n gap = \"0.7rem\",\n pauseOnHover = false,\n className = \"\",\n trackClassName = \"\",\n itemClassName = \"\",\n style,\n ...props\n}: MarqueeStripProps<T>) {\n const doubledItems = [...items, ...items];\n const mergedStyle = {\n ...style,\n [\"--marquee-duration\" as string]: `${durationSeconds}s`,\n [\"--marquee-gap\" as string]:\n typeof gap === \"number\" ? `${gap}px` : gap,\n } as React.CSSProperties;\n\n return (\n <div\n className={`${styles.root} ${pauseOnHover ? styles.pauseOnHover : \"\"} ${className}`.trim()}\n aria-label={ariaLabel}\n style={mergedStyle}\n {...props}\n >\n <div className={`${styles.track} ${trackClassName}`.trim()}>\n {doubledItems.map((item, index) => (\n <div\n key={index}\n className={`${styles.item} ${itemClassName}`.trim()}\n aria-hidden={index >= items.length}\n >\n {renderItem(item, index % items.length)}\n </div>\n ))}\n </div>\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"PageHeader.js","sourceRoot":"","sources":["../../src/components/PageHeader.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG7D,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAoB7C,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,KAAK,EACL,SAAS,GAAG,EAAE,EACd,KAAK,EACL,YAAY,EACZ,UAAU,EACV,cAAc,EACd,MAAM,EACN,UAAU,EACV,cAAc,EACd,aAAa,EACb,eAAe,GAAG,aAAa,EAC/B,eAAe,GAAG,aAAa,GACf;IAChB,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC;IAEtE,OAAO,CACL,cAAK,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,YACpD,eAAK,SAAS,EAAE,MAAM,CAAC,SAAS,aAC9B,eAAK,SAAS,EAAE,MAAM,CAAC,YAAY,aAChC,KAAK,IAAI,YAAY,CAAC,CAAC,CAAC,CACvB,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,MAAM,CAAC,WAAW,EAC7B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,UAAU,gBACL,cAAc,YAE1B,eAAM,SAAS,EAAE,MAAM,CAAC,WAAW,YAAG,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAQ,GACjE,CACV,CAAC,CAAC,CAAC,IAAI,EACR,eAAK,SAAS,EAAE,MAAM,CAAC,aAAa,aAClC,yBACG,IAAI,CAAC,CAAC,CAAC,CACN,eAAM,SAAS,EAAE,MAAM,CAAC,SAAS,YAC/B,KAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAI,GACtC,CACR,CAAC,CAAC,CAAC,IAAI,EACP,KAAK,IACH,EACJ,WAAW,CAAC,CAAC,CAAC,sBAAI,WAAW,GAAK,CAAC,CAAC,CAAC,IAAI,IACtC,IACF,EACN,eAAK,SAAS,EAAE,MAAM,CAAC,WAAW,aAC/B,KAAK,EACL,MAAM,CAAC,CAAC,CAAC,CACR,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,gBAAa,SAAS,YACvF,KAAC,IAAI,IAAC,IAAI,EAAC,aAAa,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAI,GAC3C,CACV,CAAC,CAAC,CAAC,IAAI,EACP,UAAU,CAAC,CAAC,CAAC,CACZ,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,gBAAa,eAAe,YACjG,KAAC,WAAW,IAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAI,GAC/B,CACV,CAAC,CAAC,CAAC,IAAI,EACP,cAAc,CAAC,CAAC,CAAC,CAChB,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,MAAM,CAAC,UAAU,EAC5B,OAAO,EAAE,cAAc,gBACX,WAAW,EACvB,KAAK,EAAE,WAAW,YAElB,KAAC,OAAO,IAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAI,GAC3B,CACV,CAAC,CAAC,CAAC,IAAI,IACJ,IACF,GACF,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"PageHeader.js","sourceRoot":"","sources":["../../src/components/PageHeader.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG7D,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAoB7C,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,KAAK,EACL,SAAS,GAAG,EAAE,EACd,KAAK,EACL,YAAY,EACZ,UAAU,EACV,cAAc,EACd,MAAM,EACN,UAAU,EACV,cAAc,EACd,aAAa,EACb,eAAe,GAAG,aAAa,EAC/B,eAAe,GAAG,aAAa,GACf;IAChB,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC;IAEtE,OAAO,CACL,cAAK,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,YACpD,eAAK,SAAS,EAAE,MAAM,CAAC,SAAS,aAC9B,eAAK,SAAS,EAAE,MAAM,CAAC,YAAY,aAChC,KAAK,IAAI,YAAY,CAAC,CAAC,CAAC,CACvB,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,MAAM,CAAC,WAAW,EAC7B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,UAAU,gBACL,cAAc,YAE1B,eAAM,SAAS,EAAE,MAAM,CAAC,WAAW,YAAG,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAQ,GACjE,CACV,CAAC,CAAC,CAAC,IAAI,EACR,eAAK,SAAS,EAAE,MAAM,CAAC,aAAa,aAClC,yBACG,IAAI,CAAC,CAAC,CAAC,CACN,eAAM,SAAS,EAAE,MAAM,CAAC,SAAS,YAC/B,KAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAI,GACtC,CACR,CAAC,CAAC,CAAC,IAAI,EACP,KAAK,IACH,EACJ,WAAW,CAAC,CAAC,CAAC,sBAAI,WAAW,GAAK,CAAC,CAAC,CAAC,IAAI,IACtC,IACF,EACN,eAAK,SAAS,EAAE,MAAM,CAAC,WAAW,aAC/B,KAAK,EACL,MAAM,CAAC,CAAC,CAAC,CACR,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,gBAAa,SAAS,YACvF,KAAC,IAAI,IAAC,IAAI,EAAC,aAAa,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAI,GAC3C,CACV,CAAC,CAAC,CAAC,IAAI,EACP,UAAU,CAAC,CAAC,CAAC,CACZ,iBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,gBAAa,eAAe,YACjG,KAAC,WAAW,IAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAI,GAC/B,CACV,CAAC,CAAC,CAAC,IAAI,EACP,cAAc,CAAC,CAAC,CAAC,CAChB,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,MAAM,CAAC,UAAU,EAC5B,OAAO,EAAE,cAAc,gBACX,WAAW,EACvB,KAAK,EAAE,WAAW,YAElB,KAAC,OAAO,IAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAI,GAC3B,CACV,CAAC,CAAC,CAAC,IAAI,IACJ,IACF,GACF,CACP,CAAC;AACJ,CAAC","sourcesContent":["import React, { ReactNode } from \"react\";\n\nimport { EyeIcon, Icon, SlidersIcon } from \"@steez-ui/icons\";\nimport type { SteezIconName } from \"@steez-ui/icons\";\n\nimport styles from \"./PageHeader.module.css\";\n\nexport interface PageHeaderProps {\n title: string;\n description?: string;\n icon?: SteezIconName;\n extra?: ReactNode;\n className?: string;\n brand?: ReactNode;\n onBrandClick?: () => void;\n brandTitle?: string;\n brandAriaLabel?: string;\n onBack?: () => void;\n onSettings?: () => void;\n onViewerToggle?: () => void;\n viewerVisible?: boolean;\n viewerShowLabel?: string;\n viewerHideLabel?: string;\n}\n\nexport function PageHeader({\n title,\n description,\n icon,\n extra,\n className = \"\",\n brand,\n onBrandClick,\n brandTitle,\n brandAriaLabel,\n onBack,\n onSettings,\n onViewerToggle,\n viewerVisible,\n viewerShowLabel = \"Show viewer\",\n viewerHideLabel = \"Hide viewer\",\n}: PageHeaderProps) {\n const viewerLabel = viewerVisible ? viewerHideLabel : viewerShowLabel;\n\n return (\n <div className={`${styles.header} ${className}`.trim()}>\n <div className={styles.headerRow}>\n <div className={styles.brandCluster}>\n {brand || onBrandClick ? (\n <button\n type=\"button\"\n className={styles.brandButton}\n onClick={onBrandClick}\n title={brandTitle}\n aria-label={brandAriaLabel}\n >\n <span className={styles.brandVisual}>{brand ?? title.slice(0, 1)}</span>\n </button>\n ) : null}\n <div className={styles.headerContent}>\n <h2>\n {icon ? (\n <span className={styles.titleIcon}>\n <Icon icon={icon} width={18} height={18} />\n </span>\n ) : null}\n {title}\n </h2>\n {description ? <p>{description}</p> : null}\n </div>\n </div>\n <div className={styles.headerExtra}>\n {extra}\n {onBack ? (\n <button type=\"button\" className={styles.iconButton} onClick={onBack} aria-label=\"Go back\">\n <Icon icon=\"chevronLeft\" width={18} height={18} />\n </button>\n ) : null}\n {onSettings ? (\n <button type=\"button\" className={styles.iconButton} onClick={onSettings} aria-label=\"Open settings\">\n <SlidersIcon width={18} height={18} />\n </button>\n ) : null}\n {onViewerToggle ? (\n <button\n type=\"button\"\n className={styles.iconButton}\n onClick={onViewerToggle}\n aria-label={viewerLabel}\n title={viewerLabel}\n >\n <EyeIcon width={18} height={18} />\n </button>\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"PageTemplate.js","sourceRoot":"","sources":["../../src/components/PageTemplate.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAC;AACnE,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAmC/C,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,KAAK,EACL,WAAW,EACX,IAAI,EACJ,OAAO,EACP,YAAY,EACZ,cAAc,EACd,MAAM,EACN,UAAU,EACV,KAAK,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,UAAU,EACV,cAAc,EACd,eAAe,EACf,eAAe,EACf,QAAQ,EACR,OAAO,EACP,SAAS,GAAG,IAAI,EAChB,SAAS,GAAG,EAAE,GACI;IAClB,MAAM,WAAW,GAAG,KAAK,IAAI,OAAO,CAAC;IAErC,OAAO,CACL,eAAK,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,aACjD,SAAS,CAAC,CAAC,CAAC,CACX,cAAK,SAAS,EAAE,MAAM,CAAC,MAAM,YAC3B,KAAC,UAAU,IACT,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,eAAe,EAChC,eAAe,EAAE,eAAe,GAChC,GACE,CACP,CAAC,CAAC,CAAC,IAAI,EAEP,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CACjB,cAAK,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAC,SAAS,gBAAa,GAAG,KAAK,WAAW,YAC3E,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpB,iBAEE,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EACvC,SAAS,EAAE,GAAG,MAAM,CAAC,YAAY,IAAI,YAAY,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EACtG,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,YAAY,KAAK,GAAG,CAAC,EAAE,YAErC,GAAG,CAAC,KAAK,IAPL,GAAG,CAAC,EAAE,CAQJ,CACV,CAAC,GACE,CACP,CAAC,CAAC,CAAC,IAAI,EAER,cAAK,SAAS,EAAE,MAAM,CAAC,OAAO,YAC3B,OAAO,CAAC,CAAC,CAAC,cAAK,SAAS,EAAE,MAAM,CAAC,OAAO,2BAAkB,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,GAC1E,IACF,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"PageTemplate.js","sourceRoot":"","sources":["../../src/components/PageTemplate.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAC;AACnE,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAmC/C,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,KAAK,EACL,WAAW,EACX,IAAI,EACJ,OAAO,EACP,YAAY,EACZ,cAAc,EACd,MAAM,EACN,UAAU,EACV,KAAK,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,UAAU,EACV,cAAc,EACd,eAAe,EACf,eAAe,EACf,QAAQ,EACR,OAAO,EACP,SAAS,GAAG,IAAI,EAChB,SAAS,GAAG,EAAE,GACI;IAClB,MAAM,WAAW,GAAG,KAAK,IAAI,OAAO,CAAC;IAErC,OAAO,CACL,eAAK,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,aACjD,SAAS,CAAC,CAAC,CAAC,CACX,cAAK,SAAS,EAAE,MAAM,CAAC,MAAM,YAC3B,KAAC,UAAU,IACT,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,eAAe,EAChC,eAAe,EAAE,eAAe,GAChC,GACE,CACP,CAAC,CAAC,CAAC,IAAI,EAEP,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CACjB,cAAK,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAC,SAAS,gBAAa,GAAG,KAAK,WAAW,YAC3E,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpB,iBAEE,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EACvC,SAAS,EAAE,GAAG,MAAM,CAAC,YAAY,IAAI,YAAY,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EACtG,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,YAAY,KAAK,GAAG,CAAC,EAAE,YAErC,GAAG,CAAC,KAAK,IAPL,GAAG,CAAC,EAAE,CAQJ,CACV,CAAC,GACE,CACP,CAAC,CAAC,CAAC,IAAI,EAER,cAAK,SAAS,EAAE,MAAM,CAAC,OAAO,YAC3B,OAAO,CAAC,CAAC,CAAC,cAAK,SAAS,EAAE,MAAM,CAAC,OAAO,2BAAkB,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,GAC1E,IACF,CACP,CAAC;AACJ,CAAC","sourcesContent":["import React from \"react\";\n\nimport { PageHeader, type PageHeaderProps } from \"./PageHeader.js\";\nimport styles from \"./PageTemplate.module.css\";\n\ninterface SubTab {\n id: string;\n label: string;\n}\n\nexport interface PageTemplateProps\n extends Pick<\n PageHeaderProps,\n | \"title\"\n | \"description\"\n | \"icon\"\n | \"onBack\"\n | \"onSettings\"\n | \"brand\"\n | \"onBrandClick\"\n | \"onViewerToggle\"\n | \"viewerVisible\"\n > {\n actions?: React.ReactNode;\n extra?: React.ReactNode;\n className?: string;\n subTabs?: SubTab[];\n activeSubTab?: string;\n onSubTabChange?: (tabId: string) => void;\n children?: React.ReactNode;\n loading?: boolean;\n showTitle?: boolean;\n brandTitle?: string;\n brandAriaLabel?: string;\n viewerShowLabel?: string;\n viewerHideLabel?: string;\n}\n\nexport function PageTemplate({\n title,\n actions,\n extra,\n description,\n icon,\n subTabs,\n activeSubTab,\n onSubTabChange,\n onBack,\n onSettings,\n brand,\n onBrandClick,\n onViewerToggle,\n viewerVisible,\n brandTitle,\n brandAriaLabel,\n viewerShowLabel,\n viewerHideLabel,\n children,\n loading,\n showTitle = true,\n className = \"\",\n}: PageTemplateProps) {\n const headerExtra = extra ?? actions;\n\n return (\n <div className={`${styles.root} ${className}`.trim()}>\n {showTitle ? (\n <div className={styles.header}>\n <PageHeader\n title={title}\n description={description}\n icon={icon}\n extra={headerExtra}\n onBack={onBack}\n onSettings={onSettings}\n brand={brand}\n onBrandClick={onBrandClick}\n brandTitle={brandTitle}\n brandAriaLabel={brandAriaLabel}\n onViewerToggle={onViewerToggle}\n viewerVisible={viewerVisible}\n viewerShowLabel={viewerShowLabel}\n viewerHideLabel={viewerHideLabel}\n />\n </div>\n ) : null}\n\n {subTabs?.length ? (\n <div className={styles.subTabs} role=\"tablist\" aria-label={`${title} sections`}>\n {subTabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => onSubTabChange?.(tab.id)}\n className={`${styles.subTabButton} ${activeSubTab === tab.id ? styles.subTabButtonActive : \"\"}`.trim()}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeSubTab === tab.id}\n >\n {tab.label}\n </button>\n ))}\n </div>\n ) : null}\n\n <div className={styles.content}>\n {loading ? <div className={styles.loading}>Loading...</div> : children ?? null}\n </div>\n </div>\n );\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ export interface QuickInfoItem {
3
+ icon?: React.ReactNode;
4
+ label: string;
5
+ value: string | number;
6
+ valueColor?: "default" | "success" | "warning" | "danger";
7
+ mono?: boolean;
8
+ }
9
+ export interface StorageProgress {
10
+ used: number;
11
+ limit: number;
12
+ }
13
+ export interface QuickInfoCardProps extends React.HTMLAttributes<HTMLDivElement> {
14
+ items: QuickInfoItem[];
15
+ storageProgress?: StorageProgress;
16
+ showCornerBrackets?: boolean;
17
+ }
18
+ export declare function QuickInfoCard({ items, storageProgress, className, showCornerBrackets, ...props }: QuickInfoCardProps): import("react/jsx-runtime").JSX.Element;
19
+ export default QuickInfoCard;
20
+ //# sourceMappingURL=QuickInfoCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickInfoCard.d.ts","sourceRoot":"","sources":["../../src/components/QuickInfoCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAmB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC9E,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAeD,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,eAAe,EACf,SAAc,EACd,kBAAyB,EACzB,GAAG,KAAK,EACT,EAAE,kBAAkB,2CAiEpB;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import styles from "./QuickInfoCard.module.css";
3
+ function formatFileSize(bytes) {
4
+ if (bytes === 0) {
5
+ return "0 Bytes";
6
+ }
7
+ const base = 1024;
8
+ const sizes = ["Bytes", "KB", "MB", "GB"];
9
+ const unitIndex = Math.floor(Math.log(bytes) / Math.log(base));
10
+ return `${parseFloat((bytes / Math.pow(base, unitIndex)).toFixed(2))} ${sizes[unitIndex]}`;
11
+ }
12
+ export function QuickInfoCard({ items, storageProgress, className = "", showCornerBrackets = true, ...props }) {
13
+ const storageRatio = storageProgress
14
+ ? storageProgress.used / Math.max(storageProgress.limit, 1)
15
+ : 0;
16
+ const storageToneClass = storageRatio > 0.9
17
+ ? styles.storageDanger
18
+ : storageRatio > 0.7
19
+ ? styles.storageWarning
20
+ : "";
21
+ const getValueToneClass = (color) => {
22
+ switch (color) {
23
+ case "success":
24
+ return styles.valueSuccess;
25
+ case "warning":
26
+ return styles.valueWarning;
27
+ case "danger":
28
+ return styles.valueDanger;
29
+ default:
30
+ return "";
31
+ }
32
+ };
33
+ return (_jsxs("div", { className: `${styles.card} ${showCornerBrackets ? styles.cardWithBrackets : ""} ${className}`.trim(), ...props, children: [items.map((item, index) => (_jsxs("div", { className: styles.item, children: [item.icon ? _jsx("div", { className: styles.icon, children: item.icon }) : null, _jsxs("div", { className: styles.info, children: [_jsx("span", { className: styles.label, children: item.label }), _jsx("span", { className: `${styles.value} ${item.mono ? styles.valueMono : ""} ${getValueToneClass(item.valueColor)}`.trim(), children: item.value })] })] }, `${item.label}-${index}`))), storageProgress ? (_jsxs("div", { className: styles.storageProgress, children: [_jsxs("div", { className: styles.storageProgressLabel, children: [_jsx("span", { children: "Storage" }), _jsxs("span", { className: styles.storageProgressValue, children: [formatFileSize(storageProgress.used), " /", " ", formatFileSize(storageProgress.limit)] })] }), _jsx("div", { className: styles.storageProgressBar, children: _jsx("div", { className: `${styles.storageProgressFill} ${storageToneClass}`.trim(), style: {
34
+ "--storage-progress-width": `${Math.min(storageRatio * 100, 100)}%`,
35
+ } }) })] })) : null] }));
36
+ }
37
+ export default QuickInfoCard;
38
+ //# sourceMappingURL=QuickInfoCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickInfoCard.js","sourceRoot":"","sources":["../../src/components/QuickInfoCard.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from \"react\";\n\nimport styles from \"./QuickInfoCard.module.css\";\n\nexport interface QuickInfoItem {\n icon?: React.ReactNode;\n label: string;\n value: string | number;\n valueColor?: \"default\" | \"success\" | \"warning\" | \"danger\";\n mono?: boolean;\n}\n\nexport interface StorageProgress {\n used: number;\n limit: number;\n}\n\nexport interface QuickInfoCardProps extends React.HTMLAttributes<HTMLDivElement> {\n items: QuickInfoItem[];\n storageProgress?: StorageProgress;\n showCornerBrackets?: boolean;\n}\n\nfunction formatFileSize(bytes: number) {\n if (bytes === 0) {\n return \"0 Bytes\";\n }\n\n const base = 1024;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"];\n const unitIndex = Math.floor(Math.log(bytes) / Math.log(base));\n return `${parseFloat((bytes / Math.pow(base, unitIndex)).toFixed(2))} ${\n sizes[unitIndex]\n }`;\n}\n\nexport function QuickInfoCard({\n items,\n storageProgress,\n className = \"\",\n showCornerBrackets = true,\n ...props\n}: QuickInfoCardProps) {\n const storageRatio = storageProgress\n ? storageProgress.used / Math.max(storageProgress.limit, 1)\n : 0;\n const storageToneClass =\n storageRatio > 0.9\n ? styles.storageDanger\n : storageRatio > 0.7\n ? styles.storageWarning\n : \"\";\n\n const getValueToneClass = (color?: QuickInfoItem[\"valueColor\"]) => {\n switch (color) {\n case \"success\":\n return styles.valueSuccess;\n case \"warning\":\n return styles.valueWarning;\n case \"danger\":\n return styles.valueDanger;\n default:\n return \"\";\n }\n };\n\n return (\n <div\n className={`${styles.card} ${showCornerBrackets ? styles.cardWithBrackets : \"\"} ${className}`.trim()}\n {...props}\n >\n {items.map((item, index) => (\n <div key={`${item.label}-${index}`} className={styles.item}>\n {item.icon ? <div className={styles.icon}>{item.icon}</div> : null}\n <div className={styles.info}>\n <span className={styles.label}>{item.label}</span>\n <span\n className={`${styles.value} ${item.mono ? styles.valueMono : \"\"} ${getValueToneClass(item.valueColor)}`.trim()}\n >\n {item.value}\n </span>\n </div>\n </div>\n ))}\n {storageProgress ? (\n <div className={styles.storageProgress}>\n <div className={styles.storageProgressLabel}>\n <span>Storage</span>\n <span className={styles.storageProgressValue}>\n {formatFileSize(storageProgress.used)} /{\" \"}\n {formatFileSize(storageProgress.limit)}\n </span>\n </div>\n <div className={styles.storageProgressBar}>\n <div\n className={`${styles.storageProgressFill} ${storageToneClass}`.trim()}\n style={\n {\n \"--storage-progress-width\": `${Math.min(storageRatio * 100, 100)}%`,\n } as React.CSSProperties\n }\n />\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nexport default QuickInfoCard;\n"]}
@@ -0,0 +1,138 @@
1
+ .card {
2
+ display: flex;
3
+ gap: 1.5rem;
4
+ padding: 1rem 1.5rem;
5
+ margin: 0.75rem;
6
+ background: var(--bg-secondary);
7
+ border: 1px solid var(--border-color);
8
+ flex-wrap: wrap;
9
+ position: relative;
10
+ overflow: visible;
11
+ }
12
+
13
+ .cardWithBrackets::before {
14
+ content: "";
15
+ position: absolute;
16
+ top: -0.5rem;
17
+ left: -0.5rem;
18
+ width: 0.5rem;
19
+ height: 0.5rem;
20
+ border-top: 1px solid var(--border-color);
21
+ border-left: 1px solid var(--border-color);
22
+ }
23
+
24
+ .cardWithBrackets::after {
25
+ content: "";
26
+ position: absolute;
27
+ bottom: -0.5rem;
28
+ right: -0.5rem;
29
+ width: 0.5rem;
30
+ height: 0.5rem;
31
+ border-bottom: 1px solid var(--border-color);
32
+ border-right: 1px solid var(--border-color);
33
+ }
34
+
35
+ .item {
36
+ display: flex;
37
+ align-items: center;
38
+ gap: 0.75rem;
39
+ flex: 1;
40
+ min-width: 150px;
41
+ }
42
+
43
+ .icon {
44
+ display: grid;
45
+ place-items: center;
46
+ flex-shrink: 0;
47
+ color: var(--accent-primary);
48
+ }
49
+
50
+ .icon :global(svg) {
51
+ width: 1.25rem;
52
+ height: 1.25rem;
53
+ }
54
+
55
+ .info {
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: 0.125rem;
59
+ flex: 1;
60
+ }
61
+
62
+ .label {
63
+ color: var(--text-secondary);
64
+ font-size: 0.6875rem;
65
+ font-weight: 500;
66
+ text-transform: uppercase;
67
+ letter-spacing: 0.05em;
68
+ }
69
+
70
+ .value {
71
+ color: var(--text-primary);
72
+ font-size: 1rem;
73
+ font-weight: 600;
74
+ }
75
+
76
+ .valueMono {
77
+ font-family: var(--font-mono);
78
+ }
79
+
80
+ .valueSuccess {
81
+ color: var(--color-success, #10b981);
82
+ }
83
+
84
+ .valueWarning {
85
+ color: var(--color-warning, #f59e0b);
86
+ }
87
+
88
+ .valueDanger {
89
+ color: var(--color-error, #ef4444);
90
+ }
91
+
92
+ .storageProgress {
93
+ flex: 1;
94
+ min-width: 200px;
95
+ display: flex;
96
+ flex-direction: column;
97
+ gap: 0.375rem;
98
+ }
99
+
100
+ .storageProgressLabel {
101
+ display: flex;
102
+ justify-content: space-between;
103
+ color: var(--text-secondary);
104
+ font-size: 0.6875rem;
105
+ font-weight: 500;
106
+ text-transform: uppercase;
107
+ letter-spacing: 0.05em;
108
+ }
109
+
110
+ .storageProgressValue {
111
+ color: var(--text-primary);
112
+ font-family: var(--font-mono);
113
+ font-weight: 600;
114
+ }
115
+
116
+ .storageProgressBar {
117
+ height: 8px;
118
+ background: color-mix(in srgb, var(--bg-primary) 82%, transparent);
119
+ border-radius: 4px;
120
+ overflow: hidden;
121
+ border: 1px solid var(--border-color);
122
+ }
123
+
124
+ .storageProgressFill {
125
+ height: 100%;
126
+ width: var(--storage-progress-width, 0%);
127
+ background: var(--accent-primary);
128
+ border-radius: 3px;
129
+ transition: width 220ms ease;
130
+ }
131
+
132
+ .storageWarning {
133
+ background: var(--color-warning, #f59e0b);
134
+ }
135
+
136
+ .storageDanger {
137
+ background: var(--color-error, #ef4444);
138
+ }
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import type { SteezIconProps } from "@steez-ui/icons";
3
+ export interface RuntimeOrbitNode {
4
+ id: string;
5
+ label: string;
6
+ icon: React.ComponentType<SteezIconProps>;
7
+ x: number;
8
+ y: number;
9
+ }
10
+ export interface RuntimeOrbitDiagramProps {
11
+ nodes: RuntimeOrbitNode[];
12
+ className?: string;
13
+ durationSeconds?: number;
14
+ pathOrder?: readonly string[];
15
+ iconSize?: number;
16
+ }
17
+ export declare function RuntimeOrbitDiagram({ nodes, className, durationSeconds, pathOrder, iconSize, }: RuntimeOrbitDiagramProps): import("react/jsx-runtime").JSX.Element;
18
+ export default RuntimeOrbitDiagram;
19
+ //# sourceMappingURL=RuntimeOrbitDiagram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RuntimeOrbitDiagram.d.ts","sourceRoot":"","sources":["../../src/components/RuntimeOrbitDiagram.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAItD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IAC1C,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAcD,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,SAAc,EACd,eAAqB,EACrB,SAAS,EACT,QAAa,GACd,EAAE,wBAAwB,2CA4E1B;AAED,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import styles from "./RuntimeOrbitDiagram.module.css";
4
+ function buildPath(points) {
5
+ if (points.length === 0) {
6
+ return "";
7
+ }
8
+ return `${points
9
+ .map((point, index) => `${index === 0 ? "M" : "L"} ${point.x.toFixed(2)} ${point.y.toFixed(2)}`)
10
+ .join(" ")} Z`;
11
+ }
12
+ export function RuntimeOrbitDiagram({ nodes, className = "", durationSeconds = 5.4, pathOrder, iconSize = 22, }) {
13
+ const orderedNodes = React.useMemo(() => {
14
+ if (!pathOrder?.length) {
15
+ return nodes;
16
+ }
17
+ const nodeMap = new Map(nodes.map((node) => [node.id, node]));
18
+ const sequence = pathOrder
19
+ .map((id) => nodeMap.get(id))
20
+ .filter((node) => Boolean(node));
21
+ return sequence.length === nodes.length ? sequence : nodes;
22
+ }, [nodes, pathOrder]);
23
+ const pathD = React.useMemo(() => buildPath(orderedNodes), [orderedNodes]);
24
+ const nodeSequenceIndex = React.useMemo(() => new Map(orderedNodes.map((node, index) => [node.id, index])), [orderedNodes]);
25
+ return (_jsxs("div", { className: `${styles.root} ${className}`.trim(), style: { "--orbit-duration": `${durationSeconds}s` }, children: [_jsxs("svg", { className: styles.svg, viewBox: "0 0 100 100", preserveAspectRatio: "none", "aria-hidden": "true", children: [pathD ? _jsx("path", { className: styles.track, d: pathD, pathLength: 100 }) : null, pathD ? _jsx("path", { className: styles.pathLine, d: pathD, pathLength: 100 }) : null, pathD ? (_jsx("circle", { className: styles.dot, cx: "0", cy: "0", r: "1.45", children: _jsx("animateMotion", { calcMode: "linear", dur: `${durationSeconds}s`, path: pathD, repeatCount: "indefinite" }) })) : null] }), nodes.map((node) => {
26
+ const IconComponent = node.icon;
27
+ const sequenceIndex = nodeSequenceIndex.get(node.id) ?? 0;
28
+ const nodeDelayMs = Math.round((durationSeconds * 1000 * sequenceIndex) /
29
+ Math.max(orderedNodes.length, 1) -
30
+ 120);
31
+ return (_jsxs("div", { className: styles.node, style: {
32
+ "--node-x": `${node.x}%`,
33
+ "--node-y": `${node.y}%`,
34
+ "--node-delay": `${nodeDelayMs}ms`,
35
+ }, title: node.label, children: [_jsx("div", { className: styles.nodeInner, children: _jsx(IconComponent, { width: iconSize, height: iconSize }) }), _jsx("span", { className: styles.srOnly, children: node.label })] }, node.id));
36
+ })] }));
37
+ }
38
+ export default RuntimeOrbitDiagram;
39
+ //# sourceMappingURL=RuntimeOrbitDiagram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RuntimeOrbitDiagram.js","sourceRoot":"","sources":["../../src/components/RuntimeOrbitDiagram.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from \"react\";\n\nimport type { SteezIconProps } from \"@steez-ui/icons\";\n\nimport styles from \"./RuntimeOrbitDiagram.module.css\";\n\nexport interface RuntimeOrbitNode {\n id: string;\n label: string;\n icon: React.ComponentType<SteezIconProps>;\n x: number;\n y: number;\n}\n\nexport interface RuntimeOrbitDiagramProps {\n nodes: RuntimeOrbitNode[];\n className?: string;\n durationSeconds?: number;\n pathOrder?: readonly string[];\n iconSize?: number;\n}\n\nfunction buildPath(points: RuntimeOrbitNode[]) {\n if (points.length === 0) {\n return \"\";\n }\n\n return `${points\n .map((point, index) =>\n `${index === 0 ? \"M\" : \"L\"} ${point.x.toFixed(2)} ${point.y.toFixed(2)}`,\n )\n .join(\" \")} Z`;\n}\n\nexport function RuntimeOrbitDiagram({\n nodes,\n className = \"\",\n durationSeconds = 5.4,\n pathOrder,\n iconSize = 22,\n}: RuntimeOrbitDiagramProps) {\n const orderedNodes = React.useMemo(() => {\n if (!pathOrder?.length) {\n return nodes;\n }\n\n const nodeMap = new Map(nodes.map((node) => [node.id, node] as const));\n const sequence = pathOrder\n .map((id) => nodeMap.get(id))\n .filter((node): node is RuntimeOrbitNode => Boolean(node));\n\n return sequence.length === nodes.length ? sequence : nodes;\n }, [nodes, pathOrder]);\n\n const pathD = React.useMemo(() => buildPath(orderedNodes), [orderedNodes]);\n const nodeSequenceIndex = React.useMemo(\n () => new Map(orderedNodes.map((node, index) => [node.id, index] as const)),\n [orderedNodes],\n );\n\n return (\n <div\n className={`${styles.root} ${className}`.trim()}\n style={{ \"--orbit-duration\": `${durationSeconds}s` } as React.CSSProperties}\n >\n <svg\n className={styles.svg}\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n {pathD ? <path className={styles.track} d={pathD} pathLength={100} /> : null}\n {pathD ? <path className={styles.pathLine} d={pathD} pathLength={100} /> : null}\n {pathD ? (\n <circle className={styles.dot} cx=\"0\" cy=\"0\" r=\"1.45\">\n <animateMotion\n calcMode=\"linear\"\n dur={`${durationSeconds}s`}\n path={pathD}\n repeatCount=\"indefinite\"\n />\n </circle>\n ) : null}\n </svg>\n\n {nodes.map((node) => {\n const IconComponent = node.icon;\n const sequenceIndex = nodeSequenceIndex.get(node.id) ?? 0;\n const nodeDelayMs = Math.round(\n (durationSeconds * 1000 * sequenceIndex) /\n Math.max(orderedNodes.length, 1) -\n 120,\n );\n\n return (\n <div\n key={node.id}\n className={styles.node}\n style={\n {\n \"--node-x\": `${node.x}%`,\n \"--node-y\": `${node.y}%`,\n \"--node-delay\": `${nodeDelayMs}ms`,\n } as React.CSSProperties\n }\n title={node.label}\n >\n <div className={styles.nodeInner}>\n <IconComponent width={iconSize} height={iconSize} />\n </div>\n <span className={styles.srOnly}>{node.label}</span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport default RuntimeOrbitDiagram;\n"]}
@@ -0,0 +1,160 @@
1
+ .root {
2
+ --orbit-duration: 5.4s;
3
+
4
+ position: relative;
5
+ width: min(100%, 38rem);
6
+ aspect-ratio: 1;
7
+ min-height: 22rem;
8
+ isolation: isolate;
9
+ }
10
+
11
+ .svg {
12
+ width: 100%;
13
+ height: 100%;
14
+ display: block;
15
+ overflow: visible;
16
+ }
17
+
18
+ .track {
19
+ fill: none;
20
+ stroke: color-mix(in srgb, var(--text-primary) 14%, transparent);
21
+ stroke-width: 0.8;
22
+ stroke-linecap: round;
23
+ stroke-linejoin: round;
24
+ }
25
+
26
+ .pathLine {
27
+ fill: none;
28
+ stroke: color-mix(in srgb, var(--accent-primary) 88%, transparent);
29
+ stroke-width: 1.35;
30
+ stroke-linecap: round;
31
+ stroke-linejoin: round;
32
+ stroke-dasharray: 14 86;
33
+ animation: orbitPath var(--orbit-duration) linear infinite;
34
+ }
35
+
36
+ .node {
37
+ position: absolute;
38
+ top: var(--node-y);
39
+ left: var(--node-x);
40
+ width: clamp(4.15rem, 8vw, 4.95rem);
41
+ aspect-ratio: 1;
42
+ translate: -50% -50%;
43
+ display: grid;
44
+ place-items: center;
45
+ border-radius: 999px;
46
+ color: color-mix(in srgb, var(--text-secondary) 92%, transparent);
47
+ border: 1px solid color-mix(in srgb, var(--border-color) 78%, transparent);
48
+ background: color-mix(in srgb, var(--bg-secondary) 94%, transparent);
49
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--bg-primary) 28%, transparent);
50
+ animation: orbitPulse var(--orbit-duration) linear infinite;
51
+ animation-delay: var(--node-delay);
52
+ transition:
53
+ border-color var(--tile-hover-duration, 220ms) ease,
54
+ transform var(--tile-hover-duration, 220ms) ease,
55
+ background-color var(--tile-hover-duration, 220ms) ease;
56
+ }
57
+
58
+ .node:hover {
59
+ color: var(--text-primary);
60
+ border-color: color-mix(in srgb, var(--accent-primary) 46%, var(--border-color));
61
+ transform: translateY(-1px);
62
+ }
63
+
64
+ .nodeInner {
65
+ width: calc(100% - 10px);
66
+ height: calc(100% - 10px);
67
+ display: grid;
68
+ place-items: center;
69
+ border-radius: inherit;
70
+ background: color-mix(in srgb, var(--bg-primary) 96%, transparent);
71
+ }
72
+
73
+ .nodeInner svg {
74
+ width: 48%;
75
+ height: 48%;
76
+ color: currentColor;
77
+ opacity: 0.88;
78
+ transform: scale(0.86);
79
+ transition:
80
+ opacity var(--tile-hover-duration, 220ms) ease,
81
+ transform var(--tile-hover-duration, 220ms) ease,
82
+ color var(--tile-hover-duration, 220ms) ease;
83
+ }
84
+
85
+ .node:hover .nodeInner svg {
86
+ opacity: 1;
87
+ transform: scale(0.92);
88
+ }
89
+
90
+ .dot {
91
+ fill: var(--accent-primary);
92
+ filter: drop-shadow(
93
+ 0 0 8px color-mix(in srgb, var(--accent-primary) 32%, transparent)
94
+ );
95
+ }
96
+
97
+ .srOnly {
98
+ position: absolute;
99
+ width: 1px;
100
+ height: 1px;
101
+ padding: 0;
102
+ margin: -1px;
103
+ overflow: hidden;
104
+ clip: rect(0, 0, 0, 0);
105
+ white-space: nowrap;
106
+ border: 0;
107
+ }
108
+
109
+ @keyframes orbitPath {
110
+ from {
111
+ stroke-dashoffset: 0;
112
+ }
113
+
114
+ to {
115
+ stroke-dashoffset: -100;
116
+ }
117
+ }
118
+
119
+ @keyframes orbitPulse {
120
+ 0%,
121
+ 4%,
122
+ 16%,
123
+ 100% {
124
+ color: color-mix(in srgb, var(--text-secondary) 92%, transparent);
125
+ border-color: color-mix(in srgb, var(--border-color) 78%, transparent);
126
+ background: color-mix(in srgb, var(--bg-secondary) 94%, transparent);
127
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--bg-primary) 28%, transparent);
128
+ }
129
+
130
+ 6%,
131
+ 13% {
132
+ color: var(--text-primary);
133
+ border-color: color-mix(in srgb, var(--accent-primary) 64%, var(--border-color));
134
+ background: color-mix(in srgb, var(--accent-primary) 12%, var(--bg-secondary));
135
+ box-shadow:
136
+ 0 0 0 1px color-mix(in srgb, var(--accent-primary) 24%, transparent),
137
+ 0 0 22px color-mix(in srgb, var(--accent-primary) 18%, transparent);
138
+ }
139
+ }
140
+
141
+ @media (max-width: 720px) {
142
+ .root {
143
+ min-height: 18rem;
144
+ }
145
+
146
+ .node {
147
+ width: clamp(3.55rem, 17vw, 4.25rem);
148
+ }
149
+ }
150
+
151
+ @media (prefers-reduced-motion: reduce) {
152
+ .pathLine,
153
+ .node {
154
+ animation: none;
155
+ }
156
+
157
+ .dot {
158
+ display: none;
159
+ }
160
+ }
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ export interface SectionProps extends Omit<React.HTMLAttributes<HTMLElement>, "title"> {
3
+ title?: React.ReactNode;
4
+ titleClassName?: string;
5
+ contentClassName?: string;
6
+ }
7
+ export declare function Section({ title, children, className, titleClassName, contentClassName, ...props }: SectionProps): import("react/jsx-runtime").JSX.Element;
8
+ export default Section;
9
+ //# sourceMappingURL=Section.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Section.d.ts","sourceRoot":"","sources":["../../src/components/Section.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,YACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IACxD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,SAAc,EACd,cAAmB,EACnB,gBAAqB,EACrB,GAAG,KAAK,EACT,EAAE,YAAY,2CAWd;AAED,eAAe,OAAO,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import styles from "./Section.module.css";
3
+ export function Section({ title, children, className = "", titleClassName = "", contentClassName = "", ...props }) {
4
+ return (_jsxs("section", { className: `${styles.section} ${className}`.trim(), ...props, children: [title ? (_jsx("h3", { className: `${styles.title} ${titleClassName}`.trim(), children: title })) : null, _jsx("div", { className: `${styles.content} ${contentClassName}`.trim(), children: children })] }));
5
+ }
6
+ export default Section;
7
+ //# sourceMappingURL=Section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Section.js","sourceRoot":"","sources":["../../src/components/Section.tsx"],"names":[],"mappings":";AAEA,OAAO,MAAM,MAAM,sBAAsB,CAAC;AAS1C,MAAM,UAAU,OAAO,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,SAAS,GAAG,EAAE,EACd,cAAc,GAAG,EAAE,EACnB,gBAAgB,GAAG,EAAE,EACrB,GAAG,KAAK,EACK;IACb,OAAO,CACL,mBAAS,SAAS,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,KAAM,KAAK,aACnE,KAAK,CAAC,CAAC,CAAC,CACP,aAAI,SAAS,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,cAAc,EAAE,CAAC,IAAI,EAAE,YAAG,KAAK,GAAM,CACxE,CAAC,CAAC,CAAC,IAAI,EACR,cAAK,SAAS,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,gBAAgB,EAAE,CAAC,IAAI,EAAE,YAC3D,QAAQ,GACL,IACE,CACX,CAAC;AACJ,CAAC;AAED,eAAe,OAAO,CAAC","sourcesContent":["import React from \"react\";\n\nimport styles from \"./Section.module.css\";\n\nexport interface SectionProps\n extends Omit<React.HTMLAttributes<HTMLElement>, \"title\"> {\n title?: React.ReactNode;\n titleClassName?: string;\n contentClassName?: string;\n}\n\nexport function Section({\n title,\n children,\n className = \"\",\n titleClassName = \"\",\n contentClassName = \"\",\n ...props\n}: SectionProps) {\n return (\n <section className={`${styles.section} ${className}`.trim()} {...props}>\n {title ? (\n <h3 className={`${styles.title} ${titleClassName}`.trim()}>{title}</h3>\n ) : null}\n <div className={`${styles.content} ${contentClassName}`.trim()}>\n {children}\n </div>\n </section>\n );\n}\n\nexport default Section;\n"]}
@@ -0,0 +1,20 @@
1
+ .section {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 0.85rem;
5
+ margin-bottom: 1.5rem;
6
+ }
7
+
8
+ .title {
9
+ margin: 0;
10
+ color: var(--text-primary);
11
+ font-family: var(--font-mono);
12
+ font-size: 0.9rem;
13
+ font-weight: 600;
14
+ letter-spacing: 0.08em;
15
+ text-transform: uppercase;
16
+ }
17
+
18
+ .content {
19
+ min-width: 0;
20
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ export interface SectionHeaderProps {
3
+ title: string;
4
+ description?: string;
5
+ actions?: React.ReactNode;
6
+ className?: string;
7
+ }
8
+ export declare function SectionHeader({ title, description, actions, className, }: SectionHeaderProps): import("react/jsx-runtime").JSX.Element;
9
+ export default SectionHeader;
10
+ //# sourceMappingURL=SectionHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionHeader.d.ts","sourceRoot":"","sources":["../../src/components/SectionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,OAAO,EACP,SAAc,GACf,EAAE,kBAAkB,2CAcpB;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import styles from "./SectionHeader.module.css";
3
+ export function SectionHeader({ title, description, actions, className = "", }) {
4
+ return (_jsx("div", { className: `${styles.sectionHeader} ${className}`.trim(), children: _jsxs("div", { className: styles.headerContent, children: [_jsxs("div", { className: styles.textContent, children: [_jsx("h2", { className: styles.title, children: title }), description ? (_jsx("p", { className: styles.description, children: description })) : null] }), actions ? _jsx("div", { className: styles.actions, children: actions }) : null] }) }));
5
+ }
6
+ export default SectionHeader;
7
+ //# sourceMappingURL=SectionHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionHeader.js","sourceRoot":"","sources":["../../src/components/SectionHeader.tsx"],"names":[],"mappings":";AAEA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAShD,MAAM,UAAU,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,OAAO,EACP,SAAS,GAAG,EAAE,GACK;IACnB,OAAO,CACL,cAAK,SAAS,EAAE,GAAG,MAAM,CAAC,aAAa,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,YAC3D,eAAK,SAAS,EAAE,MAAM,CAAC,aAAa,aAClC,eAAK,SAAS,EAAE,MAAM,CAAC,WAAW,aAChC,aAAI,SAAS,EAAE,MAAM,CAAC,KAAK,YAAG,KAAK,GAAM,EACxC,WAAW,CAAC,CAAC,CAAC,CACb,YAAG,SAAS,EAAE,MAAM,CAAC,WAAW,YAAG,WAAW,GAAK,CACpD,CAAC,CAAC,CAAC,IAAI,IACJ,EACL,OAAO,CAAC,CAAC,CAAC,cAAK,SAAS,EAAE,MAAM,CAAC,OAAO,YAAG,OAAO,GAAO,CAAC,CAAC,CAAC,IAAI,IAC7D,GACF,CACP,CAAC;AACJ,CAAC;AAED,eAAe,aAAa,CAAC","sourcesContent":["import React from \"react\";\n\nimport styles from \"./SectionHeader.module.css\";\n\nexport interface SectionHeaderProps {\n title: string;\n description?: string;\n actions?: React.ReactNode;\n className?: string;\n}\n\nexport function SectionHeader({\n title,\n description,\n actions,\n className = \"\",\n}: SectionHeaderProps) {\n return (\n <div className={`${styles.sectionHeader} ${className}`.trim()}>\n <div className={styles.headerContent}>\n <div className={styles.textContent}>\n <h2 className={styles.title}>{title}</h2>\n {description ? (\n <p className={styles.description}>{description}</p>\n ) : null}\n </div>\n {actions ? <div className={styles.actions}>{actions}</div> : null}\n </div>\n </div>\n );\n}\n\nexport default SectionHeader;\n"]}
@@ -0,0 +1,54 @@
1
+ .sectionHeader {
2
+ background: var(--bg-secondary);
3
+ border: 1px solid var(--border-color);
4
+ border-radius: 8px;
5
+ padding: 1rem 1.25rem;
6
+ margin-bottom: 1.25rem;
7
+ }
8
+
9
+ .headerContent {
10
+ display: flex;
11
+ justify-content: space-between;
12
+ align-items: center;
13
+ gap: 1rem;
14
+ }
15
+
16
+ .textContent {
17
+ flex: 1;
18
+ min-width: 0;
19
+ }
20
+
21
+ .title {
22
+ margin: 0 0 0.25rem;
23
+ color: var(--text-primary);
24
+ font-family: var(--font-mono);
25
+ font-size: 1rem;
26
+ font-weight: 600;
27
+ letter-spacing: 0.06em;
28
+ text-transform: uppercase;
29
+ }
30
+
31
+ .description {
32
+ margin: 0;
33
+ color: var(--text-secondary);
34
+ font-size: 0.8125rem;
35
+ line-height: 1.5;
36
+ }
37
+
38
+ .actions {
39
+ display: flex;
40
+ align-items: center;
41
+ gap: 0.5rem;
42
+ flex-shrink: 0;
43
+ }
44
+
45
+ @media (max-width: 640px) {
46
+ .headerContent {
47
+ flex-direction: column;
48
+ align-items: stretch;
49
+ }
50
+
51
+ .actions {
52
+ justify-content: flex-end;
53
+ }
54
+ }