@zendir/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +589 -0
  4. package/dist/index.d.ts +8 -0
  5. package/dist/index.js +421 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/react/3d/EarthViewer.d.ts +46 -0
  8. package/dist/react/3d/EarthViewer.js +836 -0
  9. package/dist/react/3d/EarthViewer.js.map +1 -0
  10. package/dist/react/3d/SolarSystemViewer.d.ts +43 -0
  11. package/dist/react/3d/SolarSystemViewer.js +372 -0
  12. package/dist/react/3d/SolarSystemViewer.js.map +1 -0
  13. package/dist/react/3d/ZenSpace3D.d.ts +16 -0
  14. package/dist/react/3d/ZenSpace3D.js +1253 -0
  15. package/dist/react/3d/ZenSpace3D.js.map +1 -0
  16. package/dist/react/3d/ZenSpace3DCesium.d.ts +9 -0
  17. package/dist/react/3d/ZenSpace3DCesium.js +186 -0
  18. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
  19. package/dist/react/3d/ZenSpace3DShaders.d.ts +78 -0
  20. package/dist/react/3d/ZenSpace3DShaders.js +94 -0
  21. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
  22. package/dist/react/3d/ZenSpace3DTypes.d.ts +614 -0
  23. package/dist/react/3d/ZenSpace3DUtils.d.ts +183 -0
  24. package/dist/react/3d/ZenSpace3DUtils.js +213 -0
  25. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
  26. package/dist/react/3d/index.d.ts +23 -0
  27. package/dist/react/3d/threeLoader.d.ts +22 -0
  28. package/dist/react/3d/threeLoader.js +18 -0
  29. package/dist/react/3d/threeLoader.js.map +1 -0
  30. package/dist/react/astro/ClassificationBanner.d.ts +25 -0
  31. package/dist/react/astro/ClassificationBanner.js +83 -0
  32. package/dist/react/astro/ClassificationBanner.js.map +1 -0
  33. package/dist/react/astro/GlobalStatusBar.d.ts +42 -0
  34. package/dist/react/astro/GlobalStatusBar.js +165 -0
  35. package/dist/react/astro/GlobalStatusBar.js.map +1 -0
  36. package/dist/react/astro/MissionClock.d.ts +169 -0
  37. package/dist/react/astro/MissionClock.js +411 -0
  38. package/dist/react/astro/MissionClock.js.map +1 -0
  39. package/dist/react/astro/MonitoringIcon.d.ts +60 -0
  40. package/dist/react/astro/MonitoringIcon.js +369 -0
  41. package/dist/react/astro/MonitoringIcon.js.map +1 -0
  42. package/dist/react/astro/Notification.d.ts +42 -0
  43. package/dist/react/astro/Notification.js +156 -0
  44. package/dist/react/astro/Notification.js.map +1 -0
  45. package/dist/react/astro/Progress.d.ts +39 -0
  46. package/dist/react/astro/Progress.js +149 -0
  47. package/dist/react/astro/Progress.js.map +1 -0
  48. package/dist/react/astro/SimulationControls.d.ts +136 -0
  49. package/dist/react/astro/SimulationControls.js +668 -0
  50. package/dist/react/astro/SimulationControls.js.map +1 -0
  51. package/dist/react/astro/StatusIndicator.d.ts +34 -0
  52. package/dist/react/astro/StatusIndicator.js +189 -0
  53. package/dist/react/astro/StatusIndicator.js.map +1 -0
  54. package/dist/react/astro/UnifiedTimeline.d.ts +106 -0
  55. package/dist/react/astro/UnifiedTimeline.js +1768 -0
  56. package/dist/react/astro/UnifiedTimeline.js.map +1 -0
  57. package/dist/react/astro/index.d.ts +63 -0
  58. package/dist/react/cards/AccessCard.d.ts +37 -0
  59. package/dist/react/cards/AccessCard.js +410 -0
  60. package/dist/react/cards/AccessCard.js.map +1 -0
  61. package/dist/react/cards/OrbitCard.d.ts +31 -0
  62. package/dist/react/cards/OrbitCard.js +372 -0
  63. package/dist/react/cards/OrbitCard.js.map +1 -0
  64. package/dist/react/cards/SpacecraftCard.d.ts +54 -0
  65. package/dist/react/cards/SpacecraftCard.js +941 -0
  66. package/dist/react/cards/SpacecraftCard.js.map +1 -0
  67. package/dist/react/cards/TelemetryCard.d.ts +40 -0
  68. package/dist/react/cards/TelemetryCard.js +742 -0
  69. package/dist/react/cards/TelemetryCard.js.map +1 -0
  70. package/dist/react/cards/TelemetryStreamCard.d.ts +59 -0
  71. package/dist/react/cards/TelemetryStreamCard.js +309 -0
  72. package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
  73. package/dist/react/cards/index.d.ts +13 -0
  74. package/dist/react/charts/GroundTrackMap.d.ts +112 -0
  75. package/dist/react/charts/GroundTrackMap.js +1123 -0
  76. package/dist/react/charts/GroundTrackMap.js.map +1 -0
  77. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +26 -0
  78. package/dist/react/charts/GroundTrackMapLeaflet.js +571 -0
  79. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -0
  80. package/dist/react/charts/groundTrackMapLeafletTiles.d.ts +22 -0
  81. package/dist/react/charts/groundTrackMapLeafletTiles.js +11 -0
  82. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -0
  83. package/dist/react/charts/groundTrackMapLeafletUtils.d.ts +24 -0
  84. package/dist/react/charts/groundTrackMapLeafletUtils.js +109 -0
  85. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -0
  86. package/dist/react/charts/index.d.ts +10 -0
  87. package/dist/react/charts/unified/AstroChart.d.ts +24 -0
  88. package/dist/react/charts/unified/AstroChart.js +1405 -0
  89. package/dist/react/charts/unified/AstroChart.js.map +1 -0
  90. package/dist/react/charts/unified/PowerOverviewChart.d.ts +73 -0
  91. package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
  92. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
  93. package/dist/react/charts/unified/domain.d.ts +845 -0
  94. package/dist/react/charts/unified/domain.js +3168 -0
  95. package/dist/react/charts/unified/domain.js.map +1 -0
  96. package/dist/react/charts/unified/generators.d.ts +276 -0
  97. package/dist/react/charts/unified/generators.js +518 -0
  98. package/dist/react/charts/unified/generators.js.map +1 -0
  99. package/dist/react/charts/unified/index.d.ts +55 -0
  100. package/dist/react/charts/unified/presets.d.ts +290 -0
  101. package/dist/react/charts/unified/presets.js +999 -0
  102. package/dist/react/charts/unified/presets.js.map +1 -0
  103. package/dist/react/charts/unified/sync.d.ts +69 -0
  104. package/dist/react/charts/unified/sync.js +219 -0
  105. package/dist/react/charts/unified/sync.js.map +1 -0
  106. package/dist/react/charts/unified/theme.d.ts +447 -0
  107. package/dist/react/charts/unified/theme.js +562 -0
  108. package/dist/react/charts/unified/theme.js.map +1 -0
  109. package/dist/react/charts/unified/types.d.ts +826 -0
  110. package/dist/react/charts/unified/useChartStream.d.ts +58 -0
  111. package/dist/react/charts/unified/useChartStream.js +226 -0
  112. package/dist/react/charts/unified/useChartStream.js.map +1 -0
  113. package/dist/react/chatgpt/AppCard.d.ts +59 -0
  114. package/dist/react/chatgpt/AppCard.js +306 -0
  115. package/dist/react/chatgpt/AppCard.js.map +1 -0
  116. package/dist/react/chatgpt/ChatGPTCard.d.ts +6 -0
  117. package/dist/react/chatgpt/index.d.ts +167 -0
  118. package/dist/react/chatgpt/index.js +166 -0
  119. package/dist/react/chatgpt/index.js.map +1 -0
  120. package/dist/react/context/DisplaySettingsContext.d.ts +107 -0
  121. package/dist/react/context/DisplaySettingsContext.js +169 -0
  122. package/dist/react/context/DisplaySettingsContext.js.map +1 -0
  123. package/dist/react/context/index.d.ts +5 -0
  124. package/dist/react/core/ActivityPlanner.d.ts +45 -0
  125. package/dist/react/core/ActivityPlanner.js +532 -0
  126. package/dist/react/core/ActivityPlanner.js.map +1 -0
  127. package/dist/react/core/AppBar.d.ts +71 -0
  128. package/dist/react/core/AppBar.js +817 -0
  129. package/dist/react/core/AppBar.js.map +1 -0
  130. package/dist/react/core/AstroIcon.d.ts +84 -0
  131. package/dist/react/core/AstroIcon.js +1243 -0
  132. package/dist/react/core/AstroIcon.js.map +1 -0
  133. package/dist/react/core/Badge.d.ts +27 -0
  134. package/dist/react/core/Badge.js +134 -0
  135. package/dist/react/core/Badge.js.map +1 -0
  136. package/dist/react/core/Button.d.ts +26 -0
  137. package/dist/react/core/Button.js +306 -0
  138. package/dist/react/core/Button.js.map +1 -0
  139. package/dist/react/core/CardHeader.d.ts +34 -0
  140. package/dist/react/core/CardHeader.js +316 -0
  141. package/dist/react/core/CardHeader.js.map +1 -0
  142. package/dist/react/core/ChatPanel.d.ts +627 -0
  143. package/dist/react/core/ChatPanel.js +1144 -0
  144. package/dist/react/core/ChatPanel.js.map +1 -0
  145. package/dist/react/core/Checkbox.d.ts +26 -0
  146. package/dist/react/core/Checkbox.js +130 -0
  147. package/dist/react/core/Checkbox.js.map +1 -0
  148. package/dist/react/core/ColorPickerPanel.d.ts +25 -0
  149. package/dist/react/core/ColorPickerPanel.js +293 -0
  150. package/dist/react/core/ColorPickerPanel.js.map +1 -0
  151. package/dist/react/core/CommandBuilder.d.ts +74 -0
  152. package/dist/react/core/CommandBuilder.js +518 -0
  153. package/dist/react/core/CommandBuilder.js.map +1 -0
  154. package/dist/react/core/ConfirmDialog.d.ts +45 -0
  155. package/dist/react/core/ConfirmDialog.js +315 -0
  156. package/dist/react/core/ConfirmDialog.js.map +1 -0
  157. package/dist/react/core/ConnectionForm.d.ts +57 -0
  158. package/dist/react/core/ConnectionForm.js +496 -0
  159. package/dist/react/core/ConnectionForm.js.map +1 -0
  160. package/dist/react/core/Container.d.ts +51 -0
  161. package/dist/react/core/Container.js +670 -0
  162. package/dist/react/core/Container.js.map +1 -0
  163. package/dist/react/core/CopyButton.d.ts +39 -0
  164. package/dist/react/core/CopyButton.js +105 -0
  165. package/dist/react/core/CopyButton.js.map +1 -0
  166. package/dist/react/core/DataTable.d.ts +113 -0
  167. package/dist/react/core/DataTable.js +446 -0
  168. package/dist/react/core/DataTable.js.map +1 -0
  169. package/dist/react/core/DataValue.d.ts +64 -0
  170. package/dist/react/core/DataValue.js +545 -0
  171. package/dist/react/core/DataValue.js.map +1 -0
  172. package/dist/react/core/Dialog.d.ts +32 -0
  173. package/dist/react/core/Dialog.js +201 -0
  174. package/dist/react/core/Dialog.js.map +1 -0
  175. package/dist/react/core/FileExplorer.d.ts +65 -0
  176. package/dist/react/core/FileExplorer.js +520 -0
  177. package/dist/react/core/FileExplorer.js.map +1 -0
  178. package/dist/react/core/GlassCard.d.ts +129 -0
  179. package/dist/react/core/GlassCard.js +375 -0
  180. package/dist/react/core/GlassCard.js.map +1 -0
  181. package/dist/react/core/HeaderIconWithStatus.d.ts +39 -0
  182. package/dist/react/core/HeaderIconWithStatus.js +157 -0
  183. package/dist/react/core/HeaderIconWithStatus.js.map +1 -0
  184. package/dist/react/core/HexViewer.d.ts +143 -0
  185. package/dist/react/core/HexViewer.js +1106 -0
  186. package/dist/react/core/HexViewer.js.map +1 -0
  187. package/dist/react/core/Icon.d.ts +32 -0
  188. package/dist/react/core/Icon.js +142 -0
  189. package/dist/react/core/Icon.js.map +1 -0
  190. package/dist/react/core/ImageGallery.d.ts +41 -0
  191. package/dist/react/core/ImageGallery.js +320 -0
  192. package/dist/react/core/ImageGallery.js.map +1 -0
  193. package/dist/react/core/Input.d.ts +38 -0
  194. package/dist/react/core/Input.js +288 -0
  195. package/dist/react/core/Input.js.map +1 -0
  196. package/dist/react/core/LimitsBar.d.ts +51 -0
  197. package/dist/react/core/LimitsBar.js +200 -0
  198. package/dist/react/core/LimitsBar.js.map +1 -0
  199. package/dist/react/core/LogViewer.d.ts +61 -0
  200. package/dist/react/core/LogViewer.js +599 -0
  201. package/dist/react/core/LogViewer.js.map +1 -0
  202. package/dist/react/core/MessageStream.d.ts +58 -0
  203. package/dist/react/core/MessageStream.js +455 -0
  204. package/dist/react/core/MessageStream.js.map +1 -0
  205. package/dist/react/core/MissionCalendar.d.ts +81 -0
  206. package/dist/react/core/MissionCalendar.js +1049 -0
  207. package/dist/react/core/MissionCalendar.js.map +1 -0
  208. package/dist/react/core/NumberInput.d.ts +85 -0
  209. package/dist/react/core/NumberInput.js +507 -0
  210. package/dist/react/core/NumberInput.js.map +1 -0
  211. package/dist/react/core/PacketViewer.d.ts +73 -0
  212. package/dist/react/core/PacketViewer.js +431 -0
  213. package/dist/react/core/PacketViewer.js.map +1 -0
  214. package/dist/react/core/Pagination.d.ts +30 -0
  215. package/dist/react/core/Pagination.js +190 -0
  216. package/dist/react/core/Pagination.js.map +1 -0
  217. package/dist/react/core/PinInput.d.ts +41 -0
  218. package/dist/react/core/PinInput.js +210 -0
  219. package/dist/react/core/PinInput.js.map +1 -0
  220. package/dist/react/core/Popover.d.ts +55 -0
  221. package/dist/react/core/Popover.js +288 -0
  222. package/dist/react/core/Popover.js.map +1 -0
  223. package/dist/react/core/Select.d.ts +42 -0
  224. package/dist/react/core/Select.js +303 -0
  225. package/dist/react/core/Select.js.map +1 -0
  226. package/dist/react/core/SideNav.d.ts +103 -0
  227. package/dist/react/core/SideNav.js +551 -0
  228. package/dist/react/core/SideNav.js.map +1 -0
  229. package/dist/react/core/SidePanel.d.ts +33 -0
  230. package/dist/react/core/SidePanel.js +199 -0
  231. package/dist/react/core/SidePanel.js.map +1 -0
  232. package/dist/react/core/Tabs.d.ts +47 -0
  233. package/dist/react/core/Tabs.js +129 -0
  234. package/dist/react/core/Tabs.js.map +1 -0
  235. package/dist/react/core/Toast.d.ts +56 -0
  236. package/dist/react/core/Toast.js +229 -0
  237. package/dist/react/core/Toast.js.map +1 -0
  238. package/dist/react/core/Toggle.d.ts +22 -0
  239. package/dist/react/core/Toggle.js +151 -0
  240. package/dist/react/core/Toggle.js.map +1 -0
  241. package/dist/react/core/Tooltip.d.ts +19 -0
  242. package/dist/react/core/Tooltip.js +179 -0
  243. package/dist/react/core/Tooltip.js.map +1 -0
  244. package/dist/react/core/Typography.d.ts +127 -0
  245. package/dist/react/core/Typography.js +187 -0
  246. package/dist/react/core/Typography.js.map +1 -0
  247. package/dist/react/core/index.d.ts +108 -0
  248. package/dist/react/core/layout/Box.d.ts +77 -0
  249. package/dist/react/core/layout/Box.js +126 -0
  250. package/dist/react/core/layout/Box.js.map +1 -0
  251. package/dist/react/core/layout/Center.d.ts +20 -0
  252. package/dist/react/core/layout/Center.js +34 -0
  253. package/dist/react/core/layout/Center.js.map +1 -0
  254. package/dist/react/core/layout/Divider.d.ts +16 -0
  255. package/dist/react/core/layout/Divider.js +108 -0
  256. package/dist/react/core/layout/Divider.js.map +1 -0
  257. package/dist/react/core/layout/Flex.d.ts +30 -0
  258. package/dist/react/core/layout/Flex.js +128 -0
  259. package/dist/react/core/layout/Flex.js.map +1 -0
  260. package/dist/react/core/layout/Grid.d.ts +36 -0
  261. package/dist/react/core/layout/Grid.js +142 -0
  262. package/dist/react/core/layout/Grid.js.map +1 -0
  263. package/dist/react/core/layout/Spacer.d.ts +8 -0
  264. package/dist/react/core/layout/Spacer.js +31 -0
  265. package/dist/react/core/layout/Spacer.js.map +1 -0
  266. package/dist/react/core/layout/Stack.d.ts +54 -0
  267. package/dist/react/core/layout/Stack.js +74 -0
  268. package/dist/react/core/layout/Stack.js.map +1 -0
  269. package/dist/react/core/layout/index.d.ts +38 -0
  270. package/dist/react/core/layout/responsive.d.ts +23 -0
  271. package/dist/react/core/layout/responsive.js +26 -0
  272. package/dist/react/core/layout/responsive.js.map +1 -0
  273. package/dist/react/core/layout/useBreakpoint.d.ts +77 -0
  274. package/dist/react/core/layout/useBreakpoint.js +73 -0
  275. package/dist/react/core/layout/useBreakpoint.js.map +1 -0
  276. package/dist/react/core/propertyConfig.d.ts +443 -0
  277. package/dist/react/core/propertyConfig.js +399 -0
  278. package/dist/react/core/propertyConfig.js.map +1 -0
  279. package/dist/react/hooks/index.d.ts +21 -0
  280. package/dist/react/hooks/useAccessWindows.d.ts +66 -0
  281. package/dist/react/hooks/useCompactMode.d.ts +82 -0
  282. package/dist/react/hooks/useCompactMode.js +62 -0
  283. package/dist/react/hooks/useCompactMode.js.map +1 -0
  284. package/dist/react/hooks/useLiveSelection.d.ts +57 -0
  285. package/dist/react/hooks/useSimulationPlayback.d.ts +97 -0
  286. package/dist/react/hooks/useSimulationTime.d.ts +61 -0
  287. package/dist/react/hooks/useSpacecraftPosition.d.ts +50 -0
  288. package/dist/react/hooks/useSpacecraftPosition.js +89 -0
  289. package/dist/react/hooks/useSpacecraftPosition.js.map +1 -0
  290. package/dist/react/hooks/useTelemetry.d.ts +55 -0
  291. package/dist/react/hooks/useTelemetry.js +73 -0
  292. package/dist/react/hooks/useTelemetry.js.map +1 -0
  293. package/dist/react/hooks/useZendirSession.d.ts +109 -0
  294. package/dist/react/hooks/useZendirSession.js +148 -0
  295. package/dist/react/hooks/useZendirSession.js.map +1 -0
  296. package/dist/react/index.d.ts +74 -0
  297. package/dist/react/shared/ErrorBoundary.d.ts +63 -0
  298. package/dist/react/shared/ErrorBoundary.js +142 -0
  299. package/dist/react/shared/ErrorBoundary.js.map +1 -0
  300. package/dist/react/shared/Skeleton.d.ts +110 -0
  301. package/dist/react/shared/Skeleton.js +324 -0
  302. package/dist/react/shared/Skeleton.js.map +1 -0
  303. package/dist/react/shared/index.d.ts +12 -0
  304. package/dist/react/theme/ThemeProvider.d.ts +385 -0
  305. package/dist/react/theme/ThemeProvider.js +1096 -0
  306. package/dist/react/theme/ThemeProvider.js.map +1 -0
  307. package/dist/react/theme/astro-tokens.d.ts +153 -0
  308. package/dist/react/theme/cardAccent.d.ts +75 -0
  309. package/dist/react/theme/cardAccent.js +137 -0
  310. package/dist/react/theme/cardAccent.js.map +1 -0
  311. package/dist/react/theme/config.d.ts +39 -0
  312. package/dist/react/theme/index.d.ts +9 -0
  313. package/dist/react/types.d.ts +360 -0
  314. package/dist/react/types.js +58 -0
  315. package/dist/react/types.js.map +1 -0
  316. package/dist/react/utils/index.d.ts +247 -0
  317. package/dist/react/utils/index.js +423 -0
  318. package/dist/react/utils/index.js.map +1 -0
  319. package/dist/react/visualizations/EclipseTimerCard.d.ts +17 -0
  320. package/dist/react/visualizations/EclipseTimerCard.js +250 -0
  321. package/dist/react/visualizations/EclipseTimerCard.js.map +1 -0
  322. package/dist/react/visualizations/LinkBudgetCard.d.ts +50 -0
  323. package/dist/react/visualizations/LinkBudgetCard.js +444 -0
  324. package/dist/react/visualizations/LinkBudgetCard.js.map +1 -0
  325. package/dist/react/visualizations/NavBallCard.d.ts +17 -0
  326. package/dist/react/visualizations/NavBallCard.js +243 -0
  327. package/dist/react/visualizations/NavBallCard.js.map +1 -0
  328. package/dist/react/visualizations/PropulsionCard.d.ts +37 -0
  329. package/dist/react/visualizations/PropulsionCard.js +298 -0
  330. package/dist/react/visualizations/PropulsionCard.js.map +1 -0
  331. package/dist/react/visualizations/SensorFootprintCard.d.ts +33 -0
  332. package/dist/react/visualizations/SensorFootprintCard.js +326 -0
  333. package/dist/react/visualizations/SensorFootprintCard.js.map +1 -0
  334. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +38 -0
  335. package/dist/react/visualizations/ThermalHeatmapCard.js +372 -0
  336. package/dist/react/visualizations/ThermalHeatmapCard.js.map +1 -0
  337. package/dist/react/visualizations/index.d.ts +17 -0
  338. package/dist/react.d.ts +1 -0
  339. package/dist/react.js +421 -0
  340. package/dist/react.js.map +1 -0
  341. package/dist/shaders/atmosphere.frag.js +5 -0
  342. package/dist/shaders/atmosphere.frag.js.map +1 -0
  343. package/dist/shaders/atmosphere.vert.js +5 -0
  344. package/dist/shaders/atmosphere.vert.js.map +1 -0
  345. package/dist/shaders/stars.frag.js +5 -0
  346. package/dist/shaders/stars.frag.js.map +1 -0
  347. package/dist/shaders/stars.vert.js +5 -0
  348. package/dist/shaders/stars.vert.js.map +1 -0
  349. package/dist/style.css +143 -0
  350. package/dist/tokens/index.d.ts +296 -0
  351. package/dist/tokens/index.js +263 -0
  352. package/dist/tokens/index.js.map +1 -0
  353. package/dist/tokens/tokens.css +155 -0
  354. package/dist/types/index.d.ts +23 -0
  355. package/dist/types.d.ts +1 -0
  356. package/dist/types.js +2 -0
  357. package/dist/types.js.map +1 -0
  358. package/package.json +220 -0
  359. package/sdk-stub.js +22 -0
@@ -0,0 +1,1096 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { createContext, useMemo, useState, useEffect, useContext } from "react";
3
+ function adjustHexBrightness(hex, factor) {
4
+ const normalized = hex.replace("#", "").trim();
5
+ const expanded = normalized.length === 3 ? normalized.split("").map((ch) => ch + ch).join("") : normalized;
6
+ if (!/^[0-9a-fA-F]{6}$/.test(expanded)) {
7
+ return hex;
8
+ }
9
+ const clamp = (value) => Math.max(0, Math.min(255, Math.round(value)));
10
+ const r = clamp(parseInt(expanded.slice(0, 2), 16) * factor);
11
+ const g = clamp(parseInt(expanded.slice(2, 4), 16) * factor);
12
+ const b = clamp(parseInt(expanded.slice(4, 6), 16) * factor);
13
+ const toHex = (value) => value.toString(16).padStart(2, "0");
14
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
15
+ }
16
+ function computeBorderTokens(colors) {
17
+ const thin = "1px";
18
+ const medium = "1.5px";
19
+ const thick = "2px";
20
+ const accent = colors.accent.primary;
21
+ const muted = colors.border.muted;
22
+ const critical = colors.status.critical;
23
+ const bgBase = colors.background.base;
24
+ return {
25
+ width: { thin, medium, thick },
26
+ input: {
27
+ default: `${thin} solid ${muted}`,
28
+ hover: `${thin} solid ${accent}80`,
29
+ focus: `${thin} solid ${accent}`,
30
+ error: `${thin} solid ${critical}`
31
+ },
32
+ focusRing: {
33
+ // WCAG 2.4.13: focus indicators ≥ 3:1 contrast — raised from 20%/30% to 50%/60%
34
+ default: `0 0 0 3px ${accent}50, 0 0 20px ${accent}15`,
35
+ button: `0 0 0 2px ${bgBase}, 0 0 0 4px ${accent}`,
36
+ subtle: `0 0 0 2px ${accent}60`
37
+ },
38
+ divider: `${thin} solid ${muted}`,
39
+ dropdown: `${thin} solid ${accent}30`,
40
+ separator: `${thin} solid ${muted}`
41
+ };
42
+ }
43
+ const animationTokens = {
44
+ fast: "all 150ms cubic-bezier(0.4, 0, 0.2, 1)",
45
+ normal: "all 250ms cubic-bezier(0.4, 0, 0.2, 1)",
46
+ slow: "all 400ms cubic-bezier(0.4, 0, 0.2, 1)",
47
+ spring: "all 300ms cubic-bezier(0.34, 1.56, 0.64, 1)",
48
+ easing: {
49
+ default: "cubic-bezier(0.4, 0, 0.2, 1)",
50
+ in: "ease-in",
51
+ out: "ease-out",
52
+ inOut: "ease-in-out"
53
+ },
54
+ duration: {
55
+ instant: 0,
56
+ fast: 150,
57
+ normal: 250,
58
+ slow: 400
59
+ }
60
+ };
61
+ const focusTokensDark = {
62
+ color: "#4dacff",
63
+ width: "2px",
64
+ offset: "2px",
65
+ ring: "0 0 0 2px #4dacff",
66
+ style: {
67
+ outline: "2px solid #4dacff",
68
+ outlineOffset: "2px"
69
+ }
70
+ };
71
+ const focusTokensLight = {
72
+ color: "#0066cc",
73
+ width: "2px",
74
+ offset: "2px",
75
+ ring: "0 0 0 2px #0066cc",
76
+ style: {
77
+ outline: "2px solid #0066cc",
78
+ outlineOffset: "2px"
79
+ }
80
+ };
81
+ const shadowsDark = {
82
+ none: "none",
83
+ sm: "0 1px 2px rgba(0, 0, 0, 0.3)",
84
+ md: "0 4px 8px rgba(0, 0, 0, 0.4)",
85
+ lg: "0 8px 16px rgba(0, 0, 0, 0.5)",
86
+ xl: "0 16px 32px rgba(0, 0, 0, 0.6)",
87
+ glow: (color) => `0 0 20px ${color}40, 0 0 40px ${color}20`
88
+ };
89
+ const shadowsLight = {
90
+ none: "none",
91
+ sm: "0 1px 2px rgba(0, 0, 0, 0.1)",
92
+ md: "0 4px 8px rgba(0, 0, 0, 0.15)",
93
+ lg: "0 8px 16px rgba(0, 0, 0, 0.2)",
94
+ xl: "0 16px 32px rgba(0, 0, 0, 0.25)",
95
+ glow: (color) => `0 0 20px ${color}30, 0 0 40px ${color}15`
96
+ };
97
+ const layoutTokens = {
98
+ card: {
99
+ padding: "16px",
100
+ // 4 × 4px
101
+ gap: "24px",
102
+ // 6 × 4px — desktop grid gap (matches outer padding)
103
+ gapCompact: "16px",
104
+ // 4 × 4px — mobile grid gap
105
+ heading: {
106
+ iconSize: 18,
107
+ // default card header icon (px) — matches ISS/Telemetry card header size
108
+ iconSizeCompact: 16,
109
+ // compact (e.g. chart inline header)
110
+ titleFontSize: "1rem",
111
+ // card titles (ISS, Telemetry, Mission) — reduced from 1.125rem
112
+ titleFontSizeChart: "0.875rem",
113
+ // chart titles (Power Trends) — slightly smaller
114
+ titleFontWeight: 500,
115
+ gap: 8
116
+ // gap between icon and title (px)
117
+ }
118
+ },
119
+ section: {
120
+ headerPaddingBottom: "8px",
121
+ // 2 × 4px
122
+ headerMarginBottom: "0px",
123
+ contentPaddingTop: "8px"
124
+ // 2 × 4px
125
+ },
126
+ form: {
127
+ fieldGap: "12px",
128
+ // 3 × 4px — between stacked fields
129
+ inlineGap: "12px",
130
+ // 3 × 4px — between side-by-side fields
131
+ groupPadding: "12px",
132
+ // 3 × 4px — inside grouped containers
133
+ groupGap: "12px",
134
+ // 3 × 4px — within group items
135
+ labelGap: "3px"
136
+ // label text ↔ tooltip icon
137
+ },
138
+ surface: {
139
+ padding: "12px",
140
+ // 3 × 4px
141
+ borderRadius: "12px",
142
+ // 3 × 4px
143
+ gap: "8px"
144
+ // 2 × 4px
145
+ }
146
+ };
147
+ const astroThemeDark = {
148
+ colors: {
149
+ background: {
150
+ base: "#101923",
151
+ surface: "#1b2d3e",
152
+ elevated: "#243b53",
153
+ overlay: "rgba(16, 25, 35, 0.95)"
154
+ },
155
+ border: {
156
+ default: "#2b659b",
157
+ muted: "#172635",
158
+ focus: "#4dacff"
159
+ },
160
+ text: {
161
+ primary: "#ffffff",
162
+ secondary: "#b7c5d3",
163
+ tertiary: "#8fa4b7",
164
+ muted: "#8fa4b7",
165
+ inverse: "#1b2d3e"
166
+ },
167
+ status: {
168
+ normal: "#56f000",
169
+ standby: "#2dccff",
170
+ caution: "#fce83a",
171
+ serious: "#ffb302",
172
+ critical: "#ff3838",
173
+ off: "#a4abb6"
174
+ },
175
+ semantic: {
176
+ success: "#56f000",
177
+ warning: "#fce83a",
178
+ error: "#ff3838",
179
+ info: "#4dacff"
180
+ },
181
+ accent: {
182
+ primary: "#4dacff",
183
+ secondary: "#56f000",
184
+ tertiary: "#a371f7"
185
+ },
186
+ interactive: {
187
+ default: "#4dacff",
188
+ hover: "#92cbff",
189
+ active: "#0066cc",
190
+ disabled: "#6b7280"
191
+ }
192
+ },
193
+ spacing: {
194
+ xxs: "2px",
195
+ xs: "4px",
196
+ sm: "8px",
197
+ smd: "12px",
198
+ md: "16px",
199
+ mdl: "20px",
200
+ lg: "24px",
201
+ xl: "32px",
202
+ xxl: "48px"
203
+ },
204
+ borderRadius: {
205
+ none: "0",
206
+ xs: "1px",
207
+ sm: "2px",
208
+ md: "4px",
209
+ lg: "8px",
210
+ xl: "12px",
211
+ full: "9999px"
212
+ },
213
+ elementSize: {
214
+ sm: "28px",
215
+ md: "36px",
216
+ lg: "44px"
217
+ },
218
+ typography: {
219
+ /**
220
+ * Font families per AstroUXDS specification
221
+ * @see https://www.astrouxds.com/foundations/typography/
222
+ */
223
+ fontFamily: {
224
+ /** Primary font: Roboto with comprehensive system fallbacks */
225
+ primary: '"Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif',
226
+ /** Monospace font: Roboto Mono for data/code with system fallbacks */
227
+ mono: '"Roboto Mono", "SF Mono", "Consolas", "Liberation Mono", monospace'
228
+ },
229
+ // Astro UX Display Styles
230
+ // https://www.astrouxds.com/foundations/typography/
231
+ display: {
232
+ 1: { fontSize: "3.75rem", fontWeight: 300, letterSpacing: "-0.5px", lineHeight: "4.375rem" },
233
+ 2: { fontSize: "3rem", fontWeight: 400, letterSpacing: "0", lineHeight: "3.5rem" }
234
+ },
235
+ // Astro UX Heading Styles
236
+ heading: {
237
+ 1: { fontSize: "2.125rem", fontWeight: 400, letterSpacing: "0.25px", lineHeight: "2.5rem" },
238
+ "1Bold": { fontSize: "2.125rem", fontWeight: 700, letterSpacing: "0.25px", lineHeight: "2rem" },
239
+ 2: { fontSize: "1.5rem", fontWeight: 400, letterSpacing: "0", lineHeight: "1.75rem" },
240
+ 3: { fontSize: "1.25rem", fontWeight: 500, letterSpacing: "0.15px", lineHeight: "1.5rem" },
241
+ 4: { fontSize: "1.25rem", fontWeight: 300, letterSpacing: "0.15px", lineHeight: "1.5rem" },
242
+ 5: { fontSize: "1.125rem", fontWeight: 400, letterSpacing: "0", lineHeight: "1.5rem" },
243
+ 6: { fontSize: "1.125rem", fontWeight: 300, letterSpacing: "0", lineHeight: "1.5rem" }
244
+ },
245
+ // Astro UX Body Styles
246
+ body: {
247
+ 1: { fontSize: "1rem", fontWeight: 400, letterSpacing: "0.5px", lineHeight: "1.5rem" },
248
+ "1Bold": { fontSize: "1rem", fontWeight: 700, letterSpacing: "0.5px", lineHeight: "1.5rem" },
249
+ 2: { fontSize: "0.875rem", fontWeight: 400, letterSpacing: "0.5px", lineHeight: "1.25rem" },
250
+ "2Bold": { fontSize: "0.875rem", fontWeight: 700, letterSpacing: "0.5px", lineHeight: "1.25rem" },
251
+ 3: { fontSize: "0.75rem", fontWeight: 400, letterSpacing: "0", lineHeight: "1rem" },
252
+ "3Bold": { fontSize: "0.75rem", fontWeight: 700, letterSpacing: "0", lineHeight: "1rem" }
253
+ },
254
+ // Astro UX Control Body Styles
255
+ control: {
256
+ 1: { fontSize: "1rem", fontWeight: 400, letterSpacing: "0.5px", lineHeight: "1.25rem" },
257
+ "1Bold": { fontSize: "1rem", fontWeight: 700, letterSpacing: "0.5px", lineHeight: "1.25rem" }
258
+ },
259
+ // Legacy convenience tokens (rem-based for Astro compliance)
260
+ // Note: Use Typography component for new code
261
+ fontSize: {
262
+ micro: "0.5625rem",
263
+ // 9px - very tight spaces
264
+ xxs: "0.625rem",
265
+ // 10px - compact labels (xs in old system)
266
+ xs: "0.625rem",
267
+ // 10px - compact (kept for backward compatibility)
268
+ sm: "0.75rem",
269
+ // 12px (Body 3)
270
+ base: "0.875rem",
271
+ // 14px (Body 2)
272
+ md: "0.875rem",
273
+ // 14px (Body 2)
274
+ lg: "1rem",
275
+ // 16px (Body 1)
276
+ xl: "1.25rem",
277
+ // 20px (Heading 3/4)
278
+ xxl: "1.5rem",
279
+ // 24px (Heading 2)
280
+ xxxl: "2.125rem"
281
+ // 34px (Heading 1)
282
+ },
283
+ /**
284
+ * Font weights per AstroUXDS specification
285
+ * Only 300, 400, 500, 700 are officially supported
286
+ * @see https://www.astrouxds.com/foundations/typography/
287
+ */
288
+ fontWeight: {
289
+ light: 300,
290
+ normal: 400,
291
+ medium: 500,
292
+ /** @deprecated Use medium (500) instead - Astro spec only supports 300, 400, 500, 700 */
293
+ semibold: 500,
294
+ // Changed from 600 to 500 for Astro compliance
295
+ bold: 700
296
+ },
297
+ lineHeight: {
298
+ tight: "1.25rem",
299
+ normal: "1.5rem",
300
+ relaxed: "1.75rem"
301
+ },
302
+ letterSpacing: {
303
+ tight: "-0.5px",
304
+ normal: "0",
305
+ wide: "0.5px"
306
+ }
307
+ },
308
+ shadows: shadowsDark,
309
+ animation: animationTokens,
310
+ focus: focusTokensDark,
311
+ layout: layoutTokens
312
+ };
313
+ const astroThemeLight = {
314
+ colors: {
315
+ background: {
316
+ base: "#eaeef4",
317
+ surface: "#f5f8fc",
318
+ elevated: "#ffffff",
319
+ overlay: "rgba(234, 238, 244, 0.95)"
320
+ },
321
+ border: {
322
+ default: "#2b659b",
323
+ muted: "#d1d5db",
324
+ focus: "#0066cc"
325
+ },
326
+ text: {
327
+ primary: "#1b2d3e",
328
+ secondary: "#51667c",
329
+ tertiary: "#556a7c",
330
+ // WCAG AA: 4.81:1 on #eaeef4, 5.24:1 on #f5f8fc, 5.61:1 on #fff (was #8fa4b7 → 2.25:1 FAIL)
331
+ muted: "#556a7c",
332
+ // WCAG AA compliant (was #8fa4b7)
333
+ inverse: "#ffffff"
334
+ },
335
+ status: {
336
+ normal: "#56f000",
337
+ standby: "#2dccff",
338
+ caution: "#fce83a",
339
+ serious: "#ffb302",
340
+ critical: "#ff3838",
341
+ off: "#a4abb6"
342
+ },
343
+ semantic: {
344
+ success: "#56f000",
345
+ warning: "#fce83a",
346
+ error: "#ff3838",
347
+ info: "#4dacff"
348
+ },
349
+ accent: {
350
+ primary: "#0066cc",
351
+ secondary: "#56f000",
352
+ tertiary: "#7c3aed"
353
+ },
354
+ interactive: {
355
+ default: "#0066cc",
356
+ hover: "#0052a3",
357
+ active: "#003d7a",
358
+ disabled: "#a4abb6"
359
+ }
360
+ },
361
+ spacing: astroThemeDark.spacing,
362
+ borderRadius: astroThemeDark.borderRadius,
363
+ elementSize: astroThemeDark.elementSize,
364
+ typography: astroThemeDark.typography,
365
+ shadows: shadowsLight,
366
+ animation: animationTokens,
367
+ focus: focusTokensLight,
368
+ layout: layoutTokens
369
+ };
370
+ const focusTokensPurpleHue = {
371
+ color: "#8b5cf6",
372
+ width: "2px",
373
+ offset: "2px",
374
+ ring: "0 0 0 2px #8b5cf6",
375
+ style: {
376
+ outline: "2px solid #8b5cf6",
377
+ outlineOffset: "2px"
378
+ }
379
+ };
380
+ const hybridTheme = {
381
+ colors: {
382
+ background: {
383
+ base: "#09090b",
384
+ surface: "rgba(24, 24, 27, 0.98)",
385
+ elevated: "rgba(39, 39, 42, 0.98)",
386
+ overlay: "rgba(0, 0, 0, 0.85)"
387
+ },
388
+ border: {
389
+ default: "rgba(139, 92, 246, 0.3)",
390
+ // Purple tint
391
+ muted: "rgba(63, 63, 70, 0.5)",
392
+ focus: "#8b5cf6"
393
+ // Zendir purple
394
+ },
395
+ text: {
396
+ primary: "#ffffff",
397
+ secondary: "#a1a1aa",
398
+ tertiary: "#8e8e96",
399
+ // WCAG AA: 6.12:1 on #09090b, 5.45:1 on #18181b, 4.58:1 on #27272a (was #71717a → 4.07:1 FAIL)
400
+ muted: "#8e8e96",
401
+ // WCAG AA compliant (was #71717a)
402
+ inverse: "#09090b"
403
+ },
404
+ // Astro UXD Status Colors (unchanged for compliance)
405
+ status: {
406
+ normal: "#56f000",
407
+ standby: "#2dccff",
408
+ caution: "#fce83a",
409
+ serious: "#ffb302",
410
+ critical: "#ff3838",
411
+ off: "#a4abb6"
412
+ },
413
+ semantic: {
414
+ success: "#56f000",
415
+ warning: "#fce83a",
416
+ error: "#ff3838",
417
+ info: "#8b5cf6"
418
+ // Purple for info
419
+ },
420
+ // Zendir Purple Accent Palette
421
+ accent: {
422
+ primary: "#8b5cf6",
423
+ // Vibrant purple
424
+ secondary: "#a78bfa",
425
+ // Light purple
426
+ tertiary: "#7c3aed"
427
+ // Deep purple
428
+ },
429
+ interactive: {
430
+ default: "#8b5cf6",
431
+ hover: "#a78bfa",
432
+ active: "#7c3aed",
433
+ disabled: "#52525b"
434
+ }
435
+ },
436
+ spacing: astroThemeDark.spacing,
437
+ borderRadius: {
438
+ none: "0",
439
+ xs: "2px",
440
+ sm: "4px",
441
+ md: "6px",
442
+ lg: "10px",
443
+ xl: "14px",
444
+ full: "9999px"
445
+ },
446
+ elementSize: astroThemeDark.elementSize,
447
+ typography: astroThemeDark.typography,
448
+ shadows: {
449
+ ...shadowsDark,
450
+ glow: (color) => `0 0 20px ${color}50, 0 0 40px ${color}25, 0 4px 12px ${color}20`
451
+ },
452
+ animation: animationTokens,
453
+ focus: focusTokensPurpleHue,
454
+ layout: layoutTokens
455
+ };
456
+ const purpleHueTheme = {
457
+ colors: {
458
+ background: {
459
+ base: "#0a0a0f",
460
+ surface: "rgba(18, 18, 28, 0.98)",
461
+ elevated: "rgba(28, 28, 42, 0.98)",
462
+ overlay: "rgba(0, 0, 0, 0.9)"
463
+ },
464
+ border: {
465
+ default: "rgba(139, 92, 246, 0.25)",
466
+ muted: "rgba(55, 48, 82, 0.5)",
467
+ focus: "#8b5cf6"
468
+ },
469
+ text: {
470
+ primary: "#fafafa",
471
+ secondary: "#a1a1aa",
472
+ tertiary: "#8e8e96",
473
+ // WCAG AA: 6.08:1 on #0a0a0f, 5.02:1 on elevated (was #71717a → 4.05:1 FAIL)
474
+ muted: "#8e8e96",
475
+ // WCAG AA compliant (was #71717a)
476
+ inverse: "#0a0a0f"
477
+ },
478
+ // Astro UXD Status Colors (for compliance)
479
+ status: {
480
+ normal: "#56f000",
481
+ standby: "#2dccff",
482
+ caution: "#fce83a",
483
+ serious: "#ffb302",
484
+ critical: "#ff3838",
485
+ off: "#a4abb6"
486
+ },
487
+ semantic: {
488
+ success: "#56f000",
489
+ warning: "#fce83a",
490
+ error: "#ff3838",
491
+ info: "#a78bfa"
492
+ },
493
+ // Zendir Purple Accent Palette
494
+ accent: {
495
+ primary: "#8b5cf6",
496
+ // Vibrant purple
497
+ secondary: "#a78bfa",
498
+ // Light purple
499
+ tertiary: "#7c3aed"
500
+ // Deep purple
501
+ },
502
+ interactive: {
503
+ default: "#8b5cf6",
504
+ hover: "#a78bfa",
505
+ active: "#7c3aed",
506
+ disabled: "#52525b"
507
+ }
508
+ },
509
+ spacing: astroThemeDark.spacing,
510
+ borderRadius: {
511
+ none: "0",
512
+ xs: "2px",
513
+ sm: "4px",
514
+ md: "6px",
515
+ lg: "10px",
516
+ xl: "14px",
517
+ full: "9999px"
518
+ },
519
+ elementSize: astroThemeDark.elementSize,
520
+ // Same typography as hybrid (Astro UX font stack with full fallbacks) for consistent card font across themes
521
+ typography: astroThemeDark.typography,
522
+ shadows: {
523
+ ...shadowsDark,
524
+ glow: (color) => `0 0 25px ${color}60, 0 0 50px ${color}30, 0 4px 16px ${color}25`
525
+ },
526
+ animation: animationTokens,
527
+ focus: {
528
+ ...focusTokensPurpleHue
529
+ },
530
+ layout: layoutTokens
531
+ };
532
+ const transparentTheme = {
533
+ colors: {
534
+ background: {
535
+ // Highly transparent backgrounds for glass effect
536
+ base: "rgba(8, 12, 20, 0.95)",
537
+ surface: "rgba(15, 20, 35, 0.85)",
538
+ elevated: "rgba(25, 35, 55, 0.80)",
539
+ overlay: "rgba(0, 0, 0, 0.75)"
540
+ },
541
+ border: {
542
+ // Purple accent borders (Zendir brand)
543
+ default: "rgba(139, 92, 246, 0.25)",
544
+ muted: "rgba(139, 92, 246, 0.15)",
545
+ focus: "#8b5cf6",
546
+ // Thin faded card border with purple hint
547
+ fadedBoxShadow: "inset 0 1px 0 rgba(139, 92, 246, 0.12), inset 0 -1px 0 rgba(0, 0, 0, 0.05), inset 1px 0 0 rgba(139, 92, 246, 0.06), inset -1px 0 0 rgba(139, 92, 246, 0.06)"
548
+ },
549
+ text: {
550
+ primary: "#f0f4f8",
551
+ secondary: "#94a3b8",
552
+ tertiary: "#7b8da1",
553
+ // WCAG AA: 5.71:1 on base, 5.34:1 on elevated (was #64748b → 3.66:1 FAIL)
554
+ muted: "#7b8da1",
555
+ // WCAG AA compliant (was #64748b)
556
+ inverse: "#0f172a"
557
+ },
558
+ // Astro UXD Status Colors
559
+ status: {
560
+ normal: "#56f000",
561
+ standby: "#2dccff",
562
+ caution: "#fce83a",
563
+ serious: "#ffb302",
564
+ critical: "#ff3838",
565
+ off: "#a4abb6"
566
+ },
567
+ semantic: {
568
+ success: "#56f000",
569
+ warning: "#fce83a",
570
+ error: "#ff3838",
571
+ info: "#8b5cf6"
572
+ },
573
+ // Purple accent (matching hybrid theme for consistency)
574
+ accent: {
575
+ primary: "#8b5cf6",
576
+ // Vibrant purple
577
+ secondary: "#a78bfa",
578
+ // Light purple
579
+ tertiary: "#7c3aed"
580
+ // Deep purple
581
+ },
582
+ interactive: {
583
+ default: "#8b5cf6",
584
+ // Purple for interactive elements
585
+ hover: "#a78bfa",
586
+ // Light purple on hover
587
+ active: "#7c3aed",
588
+ // Deep purple on active
589
+ disabled: "#475569",
590
+ // Purple-hue transparent backgrounds for buttons/inputs (transparent + transparent-bold)
591
+ transparentDefault: "rgba(139, 92, 246, 0.12)",
592
+ transparentHover: "rgba(139, 92, 246, 0.32)",
593
+ transparentInputBg: "rgba(139, 92, 246, 0.08)"
594
+ }
595
+ },
596
+ spacing: astroThemeDark.spacing,
597
+ borderRadius: {
598
+ none: "0",
599
+ xs: "2px",
600
+ sm: "4px",
601
+ md: "8px",
602
+ lg: "12px",
603
+ xl: "16px",
604
+ full: "9999px"
605
+ },
606
+ elementSize: astroThemeDark.elementSize,
607
+ // Same typography as hybrid for consistent card font across themes
608
+ typography: astroThemeDark.typography,
609
+ shadows: {
610
+ ...shadowsDark,
611
+ // Enhanced glow shadows for glass effect
612
+ glow: (color) => `0 0 30px ${color}50, 0 0 60px ${color}25, 0 4px 20px rgba(0,0,0,0.4)`
613
+ },
614
+ animation: animationTokens,
615
+ focus: {
616
+ color: "#8b5cf6",
617
+ // Purple focus ring
618
+ width: "2px",
619
+ offset: "2px",
620
+ ring: "0 0 0 2px #8b5cf6",
621
+ style: {
622
+ outline: "2px solid #8b5cf6",
623
+ outlineOffset: "2px"
624
+ }
625
+ },
626
+ layout: layoutTokens
627
+ };
628
+ const transparentMinimalTheme = {
629
+ colors: {
630
+ background: {
631
+ // Same as transparent theme
632
+ base: "rgba(8, 12, 20, 0.95)",
633
+ surface: "rgba(15, 20, 35, 0.85)",
634
+ elevated: "rgba(25, 35, 55, 0.80)",
635
+ overlay: "rgba(0, 0, 0, 0.75)"
636
+ },
637
+ border: {
638
+ // Accent-colored borders for minimal theme (Zendir purple)
639
+ default: "rgba(139, 92, 246, 0.25)",
640
+ muted: "rgba(139, 92, 246, 0.15)",
641
+ focus: "#8b5cf6",
642
+ // Subtle card border using accent color
643
+ fadedBoxShadow: "inset 0 1px 0 rgba(139, 92, 246, 0.1), inset 0 -1px 0 rgba(0, 0, 0, 0.1), inset 1px 0 0 rgba(139, 92, 246, 0.05), inset -1px 0 0 rgba(139, 92, 246, 0.05)"
644
+ },
645
+ text: {
646
+ primary: "#f0f4f8",
647
+ secondary: "#94a3b8",
648
+ tertiary: "#7b8da1",
649
+ // WCAG AA: 5.71:1 on base, 5.34:1 on elevated (was #64748b → 3.66:1 FAIL)
650
+ muted: "#7b8da1",
651
+ // WCAG AA compliant (was #64748b)
652
+ inverse: "#0f172a"
653
+ },
654
+ // Astro UXD Status Colors
655
+ status: {
656
+ normal: "#56f000",
657
+ standby: "#2dccff",
658
+ caution: "#fce83a",
659
+ serious: "#ffb302",
660
+ critical: "#ff3838",
661
+ off: "#a4abb6"
662
+ },
663
+ semantic: {
664
+ success: "#56f000",
665
+ warning: "#fce83a",
666
+ error: "#ff3838",
667
+ info: "#8b5cf6"
668
+ },
669
+ // Purple accent (matching transparent theme for consistency)
670
+ accent: {
671
+ primary: "#8b5cf6",
672
+ // Vibrant purple
673
+ secondary: "#a78bfa",
674
+ // Light purple
675
+ tertiary: "#7c3aed"
676
+ // Deep purple
677
+ },
678
+ interactive: {
679
+ default: "#8b5cf6",
680
+ // Purple for interactive elements
681
+ hover: "#a78bfa",
682
+ // Light purple on hover
683
+ active: "#7c3aed",
684
+ // Deep purple on active
685
+ disabled: "#475569",
686
+ // Purple-hue transparent backgrounds for buttons/inputs (same as transparent theme)
687
+ transparentDefault: "rgba(139, 92, 246, 0.12)",
688
+ transparentHover: "rgba(139, 92, 246, 0.32)",
689
+ transparentInputBg: "rgba(139, 92, 246, 0.08)"
690
+ }
691
+ },
692
+ spacing: astroThemeDark.spacing,
693
+ borderRadius: {
694
+ none: "0",
695
+ xs: "2px",
696
+ sm: "4px",
697
+ md: "8px",
698
+ lg: "12px",
699
+ xl: "16px",
700
+ full: "9999px"
701
+ },
702
+ elementSize: astroThemeDark.elementSize,
703
+ // Same typography as hybrid for consistent card font across themes
704
+ typography: astroThemeDark.typography,
705
+ shadows: {
706
+ ...shadowsDark,
707
+ // Same glow as transparent theme
708
+ glow: (color) => `0 0 30px ${color}50, 0 0 60px ${color}25, 0 4px 20px rgba(0,0,0,0.4)`
709
+ },
710
+ animation: animationTokens,
711
+ focus: {
712
+ color: "#8b5cf6",
713
+ // Purple focus ring
714
+ width: "2px",
715
+ offset: "2px",
716
+ ring: "0 0 0 2px #8b5cf6",
717
+ style: {
718
+ outline: "2px solid #8b5cf6",
719
+ outlineOffset: "2px"
720
+ }
721
+ },
722
+ layout: layoutTokens
723
+ };
724
+ const ThemeContext = createContext(void 0);
725
+ function hexToRgba(hex, alpha) {
726
+ const clean = hex.replace("#", "");
727
+ let r, g, b;
728
+ if (clean.length === 3) {
729
+ r = parseInt(clean[0] + clean[0], 16);
730
+ g = parseInt(clean[1] + clean[1], 16);
731
+ b = parseInt(clean[2] + clean[2], 16);
732
+ } else {
733
+ r = parseInt(clean.slice(0, 2), 16);
734
+ g = parseInt(clean.slice(2, 4), 16);
735
+ b = parseInt(clean.slice(4, 6), 16);
736
+ }
737
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
738
+ }
739
+ function buildScrollbarCSS(tokens, mode, reducedMotion) {
740
+ const accent = tokens.colors.accent.primary;
741
+ tokens.colors.background.surface;
742
+ tokens.colors.background.base;
743
+ const isLight = mode === "light";
744
+ const thumbRest = isLight ? hexToRgba(accent, 0.28) : hexToRgba(accent, 0.35);
745
+ const thumbHover = isLight ? hexToRgba(accent, 0.48) : hexToRgba(accent, 0.55);
746
+ const thumbActive = isLight ? hexToRgba(accent, 0.64) : hexToRgba(accent, 0.72);
747
+ const trackColor = isLight ? hexToRgba(accent, 0.04) : hexToRgba(accent, 0.06);
748
+ const trackHover = isLight ? hexToRgba(accent, 0.08) : hexToRgba(accent, 0.1);
749
+ const transition = reducedMotion ? "none" : "background-color 200ms ease, width 200ms ease, opacity 200ms ease";
750
+ const thumbRadius = "9999px";
751
+ const ffThumb = thumbRest;
752
+ const ffTrack = trackColor;
753
+ return `
754
+ /* ═══════════════════════════════════════════════════════════════════════════
755
+ Zendir Scrollbar System — Thin · Elegant · Theme-Connected
756
+ ═══════════════════════════════════════════════════════════════════════════ */
757
+
758
+ /* ── Firefox ────────────────────────────────────────────────────────────── */
759
+ *,
760
+ .zendir-scroll {
761
+ scrollbar-width: thin;
762
+ scrollbar-color: ${ffThumb} ${ffTrack};
763
+ }
764
+
765
+ /* ── Webkit / Blink (Chrome, Edge, Safari, Opera) ───────────────────────── */
766
+
767
+ /* Global thin scrollbar */
768
+ ::-webkit-scrollbar {
769
+ width: 6px;
770
+ height: 6px;
771
+ background: transparent;
772
+ }
773
+
774
+ /* Track — nearly invisible, subtle on hover */
775
+ ::-webkit-scrollbar-track {
776
+ background: ${trackColor};
777
+ border-radius: ${thumbRadius};
778
+ margin: 2px;
779
+ }
780
+ ::-webkit-scrollbar-track:hover {
781
+ background: ${trackHover};
782
+ }
783
+
784
+ /* Thumb — accent-tinted pill */
785
+ ::-webkit-scrollbar-thumb {
786
+ background: ${thumbRest};
787
+ border-radius: ${thumbRadius};
788
+ border: 1px solid transparent;
789
+ background-clip: padding-box;
790
+ transition: ${transition};
791
+ min-height: 32px;
792
+ }
793
+ ::-webkit-scrollbar-thumb:hover {
794
+ background: ${thumbHover};
795
+ border-color: transparent;
796
+ background-clip: padding-box;
797
+ }
798
+ ::-webkit-scrollbar-thumb:active {
799
+ background: ${thumbActive};
800
+ border-color: transparent;
801
+ background-clip: padding-box;
802
+ }
803
+
804
+ /* Corner — where horizontal & vertical scrollbars meet */
805
+ ::-webkit-scrollbar-corner {
806
+ background: transparent;
807
+ }
808
+
809
+ /* ── Utility class: zendir-scroll ────────────────────────────────────────
810
+ Apply to individual containers for scoped thin scrollbar.
811
+ Also enables overlay behaviour where supported.
812
+ e.g. <div className="zendir-scroll" style={{overflow:'auto'}}>…</div>
813
+ ─────────────────────────────────────────────────────────────────────── */
814
+ .zendir-scroll {
815
+ overflow: auto;
816
+ overflow: overlay; /* Chrome / Edge: auto-hide scrollbar */
817
+ }
818
+ .zendir-scroll::-webkit-scrollbar {
819
+ width: 5px;
820
+ height: 5px;
821
+ }
822
+ .zendir-scroll::-webkit-scrollbar-track {
823
+ background: transparent;
824
+ border-radius: ${thumbRadius};
825
+ }
826
+ .zendir-scroll::-webkit-scrollbar-thumb {
827
+ background: ${thumbRest};
828
+ border-radius: ${thumbRadius};
829
+ transition: ${transition};
830
+ }
831
+ .zendir-scroll::-webkit-scrollbar-thumb:hover {
832
+ background: ${thumbHover};
833
+ }
834
+ .zendir-scroll::-webkit-scrollbar-thumb:active {
835
+ background: ${thumbActive};
836
+ }
837
+
838
+ /* ── Utility: zendir-scroll--hidden ─────────────────────────────────────
839
+ Hides scrollbar visually but keeps scroll behaviour (accessible).
840
+ Content remains scrollable via mouse wheel / touch / keyboard.
841
+ ─────────────────────────────────────────────────────────────────────── */
842
+ .zendir-scroll--hidden {
843
+ overflow: auto;
844
+ -ms-overflow-style: none;
845
+ scrollbar-width: none;
846
+ }
847
+ .zendir-scroll--hidden::-webkit-scrollbar {
848
+ display: none;
849
+ }
850
+
851
+ /* ── Focus-visible: keyboard users can still scroll with focus ─────────── */
852
+ .zendir-scroll:focus-visible {
853
+ outline: 2px solid ${accent};
854
+ outline-offset: -2px;
855
+ border-radius: ${tokens.borderRadius.md};
856
+ }
857
+
858
+ /* ── Reduced Motion: disable scrollbar transitions ─────────────────────── */
859
+ @media (prefers-reduced-motion: reduce) {
860
+ ::-webkit-scrollbar-thumb,
861
+ .zendir-scroll::-webkit-scrollbar-thumb {
862
+ transition: none !important;
863
+ }
864
+ }
865
+
866
+ /* ── High Contrast Mode: ensure scrollbar is visible ───────────────────── */
867
+ @media (forced-colors: active) {
868
+ ::-webkit-scrollbar-thumb {
869
+ background: ButtonText !important;
870
+ }
871
+ ::-webkit-scrollbar-track {
872
+ background: Canvas !important;
873
+ }
874
+ }
875
+ `.trim();
876
+ }
877
+ function useScrollbarStyles() {
878
+ const { tokens, mode } = useTheme();
879
+ return useMemo(() => {
880
+ const accent = tokens.colors.accent.primary;
881
+ const isLight = mode === "light";
882
+ const thumbColor = isLight ? hexToRgba(accent, 0.28) : hexToRgba(accent, 0.35);
883
+ const trackColor = isLight ? hexToRgba(accent, 0.04) : hexToRgba(accent, 0.06);
884
+ return {
885
+ // Firefox
886
+ scrollbarWidth: "thin",
887
+ scrollbarColor: `${thumbColor} ${trackColor}`,
888
+ overflow: "auto"
889
+ };
890
+ }, [tokens, mode]);
891
+ }
892
+ function ThemeProvider({
893
+ children,
894
+ theme: defaultTheme = "hybrid",
895
+ mode: defaultMode = "dark",
896
+ persist = true
897
+ }) {
898
+ const [theme, setThemeState] = useState(() => {
899
+ if (persist && typeof window !== "undefined") {
900
+ const saved = localStorage.getItem("zendir-ui-theme");
901
+ if (saved === "astro" || saved === "zendir" || saved === "hybrid" || saved === "transparent" || saved === "transparent-bold" || saved === "transparent-minimal") {
902
+ return saved;
903
+ }
904
+ }
905
+ return defaultTheme;
906
+ });
907
+ const [mode, setModeState] = useState(() => {
908
+ if (persist && typeof window !== "undefined") {
909
+ const saved = localStorage.getItem("zendir-ui-mode");
910
+ if (saved === "light" || saved === "dark") {
911
+ return saved;
912
+ }
913
+ }
914
+ return defaultMode;
915
+ });
916
+ const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);
917
+ useEffect(() => {
918
+ if (typeof window === "undefined") return;
919
+ const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
920
+ setPrefersReducedMotion(mediaQuery.matches);
921
+ const handler = (e) => setPrefersReducedMotion(e.matches);
922
+ mediaQuery.addEventListener("change", handler);
923
+ return () => mediaQuery.removeEventListener("change", handler);
924
+ }, []);
925
+ const setTheme = (newTheme) => {
926
+ setThemeState(newTheme);
927
+ if (persist && typeof window !== "undefined") {
928
+ localStorage.setItem("zendir-ui-theme", newTheme);
929
+ }
930
+ };
931
+ const setMode = (newMode) => {
932
+ setModeState(newMode);
933
+ if (persist && typeof window !== "undefined") {
934
+ localStorage.setItem("zendir-ui-mode", newMode);
935
+ }
936
+ };
937
+ const toggleMode = () => {
938
+ setMode(mode === "dark" ? "light" : "dark");
939
+ };
940
+ const [accentColor, setAccentColorState] = useState(() => {
941
+ if (persist && typeof window !== "undefined") {
942
+ return localStorage.getItem("zendir-ui-accent") || null;
943
+ }
944
+ return null;
945
+ });
946
+ const setAccentColor = (color) => {
947
+ setAccentColorState(color);
948
+ if (persist && typeof window !== "undefined") {
949
+ if (color) {
950
+ localStorage.setItem("zendir-ui-accent", color);
951
+ } else {
952
+ localStorage.removeItem("zendir-ui-accent");
953
+ }
954
+ }
955
+ };
956
+ const tokens = useMemo(() => {
957
+ const base = mode === "light" ? astroThemeLight : theme === "astro" ? astroThemeDark : theme === "hybrid" ? hybridTheme : theme === "transparent" || theme === "transparent-bold" ? transparentTheme : theme === "transparent-minimal" ? transparentMinimalTheme : purpleHueTheme;
958
+ const isTransparent = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
959
+ const isMinimal = theme === "transparent-minimal";
960
+ const resolvedAccent = isTransparent && accentColor ? {
961
+ primary: accentColor,
962
+ secondary: adjustHexBrightness(accentColor, 1.2),
963
+ tertiary: adjustHexBrightness(accentColor, 0.85)
964
+ } : base.colors.accent;
965
+ const accentPrimary = resolvedAccent.primary;
966
+ const accentBorderMuted = `${accentPrimary}40`;
967
+ const accentBorderDefault = `${accentPrimary}66`;
968
+ const accentFadedBoxShadow = `inset 0 1px 0 ${hexToRgba(accentPrimary, 0.12)}, inset 0 -1px 0 rgba(0, 0, 0, 0.05), inset 1px 0 0 ${hexToRgba(accentPrimary, 0.06)}, inset -1px 0 0 ${hexToRgba(accentPrimary, 0.06)}`;
969
+ const cardStyle = isMinimal ? { border: `1px solid ${accentBorderMuted}` } : isTransparent ? { border: "none", boxShadow: accentFadedBoxShadow } : { border: `1px solid ${base.colors.border.muted}` };
970
+ const cardStyleDashed = isMinimal ? { border: `1px dashed ${accentBorderMuted}` } : isTransparent ? { border: "none", boxShadow: accentFadedBoxShadow } : { border: `1px dashed ${base.colors.border.muted}` };
971
+ const cardStyleDefault = isMinimal ? { border: `1px solid ${accentBorderDefault}` } : isTransparent ? { border: "none", boxShadow: accentFadedBoxShadow } : { border: `1px solid ${base.colors.border.default}` };
972
+ const resolvedColors = {
973
+ ...base.colors,
974
+ accent: resolvedAccent,
975
+ border: {
976
+ ...base.colors.border,
977
+ cardStyle,
978
+ cardStyleDashed,
979
+ cardStyleDefault
980
+ }
981
+ };
982
+ return {
983
+ ...base,
984
+ colors: resolvedColors,
985
+ borders: computeBorderTokens(resolvedColors)
986
+ };
987
+ }, [theme, mode, accentColor]);
988
+ useEffect(() => {
989
+ if (typeof document === "undefined") return;
990
+ const root = document.documentElement;
991
+ const { colors, typography, spacing, borderRadius, animation, focus, shadows } = tokens;
992
+ root.setAttribute("data-theme", mode);
993
+ root.setAttribute("data-variant", theme);
994
+ root.style.setProperty("--color-background-base", colors.background.base);
995
+ root.style.setProperty("--color-background-surface", colors.background.surface);
996
+ root.style.setProperty("--color-background-elevated", colors.background.elevated);
997
+ root.style.setProperty("--color-background-overlay", colors.background.overlay);
998
+ root.style.setProperty("--color-border", colors.border.default);
999
+ root.style.setProperty("--color-border-muted", colors.border.muted);
1000
+ root.style.setProperty("--color-border-focus", colors.border.focus);
1001
+ root.style.setProperty("--color-text-primary", colors.text.primary);
1002
+ root.style.setProperty("--color-text-secondary", colors.text.secondary);
1003
+ root.style.setProperty("--color-text-tertiary", colors.text.tertiary);
1004
+ root.style.setProperty("--color-text-inverse", colors.text.inverse);
1005
+ root.style.setProperty("--color-status-normal", colors.status.normal);
1006
+ root.style.setProperty("--color-status-standby", colors.status.standby);
1007
+ root.style.setProperty("--color-status-caution", colors.status.caution);
1008
+ root.style.setProperty("--color-status-serious", colors.status.serious);
1009
+ root.style.setProperty("--color-status-critical", colors.status.critical);
1010
+ root.style.setProperty("--color-status-off", colors.status.off);
1011
+ root.style.setProperty("--color-interactive-default", colors.interactive.default);
1012
+ root.style.setProperty("--color-interactive-hover", colors.interactive.hover);
1013
+ root.style.setProperty("--color-interactive-active", colors.interactive.active);
1014
+ root.style.setProperty("--color-interactive-disabled", colors.interactive.disabled);
1015
+ root.style.setProperty("--color-accent-primary", colors.accent.primary);
1016
+ root.style.setProperty("--color-accent-secondary", colors.accent.secondary);
1017
+ root.style.setProperty("--color-accent-tertiary", colors.accent.tertiary);
1018
+ root.style.setProperty("--font-family-primary", typography.fontFamily.primary);
1019
+ root.style.setProperty("--font-family-mono", typography.fontFamily.mono);
1020
+ root.style.setProperty("--spacing-xxs", spacing.xxs);
1021
+ root.style.setProperty("--spacing-xs", spacing.xs);
1022
+ root.style.setProperty("--spacing-sm", spacing.sm);
1023
+ root.style.setProperty("--spacing-smd", spacing.smd);
1024
+ root.style.setProperty("--spacing-md", spacing.md);
1025
+ root.style.setProperty("--spacing-mdl", spacing.mdl);
1026
+ root.style.setProperty("--spacing-lg", spacing.lg);
1027
+ root.style.setProperty("--spacing-xl", spacing.xl);
1028
+ root.style.setProperty("--spacing-xxl", spacing.xxl);
1029
+ root.style.setProperty("--radius-sm", borderRadius.sm);
1030
+ root.style.setProperty("--radius-md", borderRadius.md);
1031
+ root.style.setProperty("--radius-lg", borderRadius.lg);
1032
+ root.style.setProperty("--radius-xl", borderRadius.xl);
1033
+ const motionMultiplier = prefersReducedMotion ? 0 : 1;
1034
+ root.style.setProperty("--animation-fast", prefersReducedMotion ? "none" : animation.fast);
1035
+ root.style.setProperty("--animation-normal", prefersReducedMotion ? "none" : animation.normal);
1036
+ root.style.setProperty("--animation-slow", prefersReducedMotion ? "none" : animation.slow);
1037
+ root.style.setProperty("--duration-fast", `${animation.duration.fast * motionMultiplier}ms`);
1038
+ root.style.setProperty("--duration-normal", `${animation.duration.normal * motionMultiplier}ms`);
1039
+ root.style.setProperty("--duration-slow", `${animation.duration.slow * motionMultiplier}ms`);
1040
+ root.style.setProperty("--focus-ring-color", focus.color);
1041
+ root.style.setProperty("--focus-ring-width", focus.width);
1042
+ root.style.setProperty("--focus-ring-offset", focus.offset);
1043
+ root.style.setProperty("--shadow-sm", shadows.sm);
1044
+ root.style.setProperty("--shadow-md", shadows.md);
1045
+ root.style.setProperty("--shadow-lg", shadows.lg);
1046
+ root.style.setProperty("--shadow-xl", shadows.xl);
1047
+ document.body.style.backgroundColor = colors.background.base;
1048
+ document.body.style.color = colors.text.primary;
1049
+ document.body.style.fontFamily = typography.fontFamily.primary;
1050
+ }, [tokens, theme, mode, prefersReducedMotion]);
1051
+ const scrollbarCSS = useMemo(() => buildScrollbarCSS(tokens, mode, prefersReducedMotion), [tokens, mode, prefersReducedMotion]);
1052
+ const value = useMemo(
1053
+ () => ({
1054
+ theme,
1055
+ mode,
1056
+ tokens,
1057
+ prefersReducedMotion,
1058
+ accentColor,
1059
+ setTheme,
1060
+ setMode,
1061
+ toggleMode,
1062
+ setAccentColor
1063
+ }),
1064
+ [theme, mode, tokens, prefersReducedMotion, accentColor]
1065
+ );
1066
+ const reducedMotionCSS = `@media (prefers-reduced-motion: reduce) {
1067
+ *, *::before, *::after {
1068
+ animation-duration: 0.01ms !important;
1069
+ animation-iteration-count: 1 !important;
1070
+ transition-duration: 0.01ms !important;
1071
+ scroll-behavior: auto !important;
1072
+ }
1073
+ }`;
1074
+ return /* @__PURE__ */ jsxs(ThemeContext.Provider, { value, children: [
1075
+ /* @__PURE__ */ jsx("style", { "data-zendir-scrollbar": "", children: scrollbarCSS }),
1076
+ /* @__PURE__ */ jsx("style", { "data-zendir-reduced-motion": "", children: reducedMotionCSS }),
1077
+ children
1078
+ ] });
1079
+ }
1080
+ function useTheme() {
1081
+ const context = useContext(ThemeContext);
1082
+ if (!context) {
1083
+ throw new Error("useTheme must be used within a ThemeProvider");
1084
+ }
1085
+ return context;
1086
+ }
1087
+ function useThemeTokens() {
1088
+ return useTheme().tokens;
1089
+ }
1090
+ export {
1091
+ ThemeProvider,
1092
+ useScrollbarStyles,
1093
+ useTheme,
1094
+ useThemeTokens
1095
+ };
1096
+ //# sourceMappingURL=ThemeProvider.js.map