@zendir/ui 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/index.js +0 -137
  2. package/dist/index.js.map +1 -1
  3. package/dist/react/context/DisplaySettingsContext.js +0 -12
  4. package/dist/react/context/DisplaySettingsContext.js.map +1 -1
  5. package/dist/react/index.d.ts +0 -30
  6. package/dist/react/utils/index.js +0 -8
  7. package/dist/react/utils/index.js.map +1 -1
  8. package/dist/react.js +0 -137
  9. package/dist/react.js.map +1 -1
  10. package/package.json +1 -1
  11. package/dist/react/3d/EarthViewer.js +0 -836
  12. package/dist/react/3d/EarthViewer.js.map +0 -1
  13. package/dist/react/3d/SolarSystemViewer.js +0 -372
  14. package/dist/react/3d/SolarSystemViewer.js.map +0 -1
  15. package/dist/react/3d/ZenSpace3D.js +0 -1253
  16. package/dist/react/3d/ZenSpace3D.js.map +0 -1
  17. package/dist/react/3d/ZenSpace3DCesium.js +0 -186
  18. package/dist/react/3d/ZenSpace3DCesium.js.map +0 -1
  19. package/dist/react/3d/ZenSpace3DShaders.js +0 -94
  20. package/dist/react/3d/ZenSpace3DShaders.js.map +0 -1
  21. package/dist/react/3d/ZenSpace3DUtils.js +0 -213
  22. package/dist/react/3d/ZenSpace3DUtils.js.map +0 -1
  23. package/dist/react/3d/threeLoader.js +0 -18
  24. package/dist/react/3d/threeLoader.js.map +0 -1
  25. package/dist/react/cards/AccessCard.js +0 -410
  26. package/dist/react/cards/AccessCard.js.map +0 -1
  27. package/dist/react/cards/OrbitCard.js +0 -372
  28. package/dist/react/cards/OrbitCard.js.map +0 -1
  29. package/dist/react/cards/SpacecraftCard.js +0 -941
  30. package/dist/react/cards/SpacecraftCard.js.map +0 -1
  31. package/dist/react/cards/TelemetryCard.js +0 -742
  32. package/dist/react/cards/TelemetryCard.js.map +0 -1
  33. package/dist/react/cards/TelemetryStreamCard.js +0 -309
  34. package/dist/react/cards/TelemetryStreamCard.js.map +0 -1
  35. package/dist/react/charts/GroundTrackMap.js +0 -1123
  36. package/dist/react/charts/GroundTrackMap.js.map +0 -1
  37. package/dist/react/charts/GroundTrackMapLeaflet.js +0 -571
  38. package/dist/react/charts/GroundTrackMapLeaflet.js.map +0 -1
  39. package/dist/react/charts/groundTrackMapLeafletTiles.js +0 -11
  40. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +0 -1
  41. package/dist/react/charts/groundTrackMapLeafletUtils.js +0 -109
  42. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +0 -1
  43. package/dist/react/charts/unified/AstroChart.js +0 -1405
  44. package/dist/react/charts/unified/AstroChart.js.map +0 -1
  45. package/dist/react/charts/unified/PowerOverviewChart.js +0 -488
  46. package/dist/react/charts/unified/PowerOverviewChart.js.map +0 -1
  47. package/dist/react/charts/unified/domain.js +0 -3168
  48. package/dist/react/charts/unified/domain.js.map +0 -1
  49. package/dist/react/charts/unified/generators.js +0 -518
  50. package/dist/react/charts/unified/generators.js.map +0 -1
  51. package/dist/react/charts/unified/presets.js +0 -999
  52. package/dist/react/charts/unified/presets.js.map +0 -1
  53. package/dist/react/charts/unified/sync.js +0 -219
  54. package/dist/react/charts/unified/sync.js.map +0 -1
  55. package/dist/react/charts/unified/theme.js +0 -562
  56. package/dist/react/charts/unified/theme.js.map +0 -1
  57. package/dist/react/charts/unified/useChartStream.js +0 -226
  58. package/dist/react/charts/unified/useChartStream.js.map +0 -1
  59. package/dist/react/visualizations/EclipseTimerCard.js +0 -250
  60. package/dist/react/visualizations/EclipseTimerCard.js.map +0 -1
  61. package/dist/react/visualizations/LinkBudgetCard.js +0 -444
  62. package/dist/react/visualizations/LinkBudgetCard.js.map +0 -1
  63. package/dist/react/visualizations/NavBallCard.js +0 -243
  64. package/dist/react/visualizations/NavBallCard.js.map +0 -1
  65. package/dist/react/visualizations/PropulsionCard.js +0 -298
  66. package/dist/react/visualizations/PropulsionCard.js.map +0 -1
  67. package/dist/react/visualizations/SensorFootprintCard.js +0 -326
  68. package/dist/react/visualizations/SensorFootprintCard.js.map +0 -1
  69. package/dist/react/visualizations/ThermalHeatmapCard.js +0 -372
  70. package/dist/react/visualizations/ThermalHeatmapCard.js.map +0 -1
  71. package/dist/shaders/atmosphere.frag.js +0 -5
  72. package/dist/shaders/atmosphere.frag.js.map +0 -1
  73. package/dist/shaders/atmosphere.vert.js +0 -5
  74. package/dist/shaders/atmosphere.vert.js.map +0 -1
  75. package/dist/shaders/stars.frag.js +0 -5
  76. package/dist/shaders/stars.frag.js.map +0 -1
  77. package/dist/shaders/stars.vert.js +0 -5
  78. package/dist/shaders/stars.vert.js.map +0 -1
  79. package/dist/style.css +0 -143
@@ -1,243 +0,0 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { useMemo } from "react";
3
- import { safeAccentText } from "../utils/index.js";
4
- import { useTheme } from "../theme/ThemeProvider.js";
5
- const NavBallCard = ({
6
- attitude,
7
- pointingMode = "nadir",
8
- targetName,
9
- compact = false,
10
- className = ""
11
- }) => {
12
- const { tokens, theme } = useTheme();
13
- const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
14
- const cardBg = isTransparentTheme ? "transparent" : tokens.colors.background.surface;
15
- const cardGlass = isTransparentTheme ? {
16
- backdropFilter: "blur(12px)",
17
- WebkitBackdropFilter: "blur(12px)"
18
- } : {};
19
- const { roll, pitch, yaw } = attitude.eulerAngles;
20
- const pointingError = attitude.pointingError ?? 0;
21
- const horizonTransform = useMemo(() => {
22
- const pitchClamp = Math.max(-45, Math.min(45, pitch));
23
- const rollClamp = Math.max(-180, Math.min(180, roll));
24
- return {
25
- transform: `rotate(${rollClamp}deg) translateY(${pitchClamp * 1.5}%)`
26
- };
27
- }, [pitch, roll]);
28
- const formatAngle = (angle, prefix) => {
29
- const sign = angle >= 0 ? "+" : "";
30
- return `${prefix}: ${sign}${angle.toFixed(1)}°`;
31
- };
32
- const statusColors = {
33
- normal: "#6ed86e",
34
- caution: "#ffd54f",
35
- critical: "#e57373",
36
- standby: "#4fc3f7"
37
- };
38
- const errorColor = useMemo(() => {
39
- if (pointingError < 0.5) return statusColors.normal;
40
- if (pointingError < 2) return statusColors.caution;
41
- return statusColors.critical;
42
- }, [pointingError]);
43
- const sizeStyle = compact ? { width: "96px", height: "96px" } : { width: "160px", height: "160px" };
44
- const cardStyle = {
45
- backgroundColor: cardBg,
46
- ...cardGlass,
47
- border: "none",
48
- borderRadius: tokens.borderRadius.lg,
49
- padding: tokens.spacing.md,
50
- fontFamily: tokens.typography.fontFamily.primary,
51
- color: tokens.colors.text.primary
52
- };
53
- return /* @__PURE__ */ jsxs("div", { className, style: cardStyle, children: [
54
- !compact && /* @__PURE__ */ jsxs("div", { style: {
55
- display: "flex",
56
- justifyContent: "space-between",
57
- alignItems: "center",
58
- marginBottom: tokens.spacing.md
59
- }, children: [
60
- /* @__PURE__ */ jsxs("div", { children: [
61
- /* @__PURE__ */ jsx("h3", { style: {
62
- fontWeight: tokens.typography.fontWeight.medium,
63
- fontSize: tokens.typography.fontSize.md,
64
- color: tokens.colors.text.primary,
65
- margin: 0
66
- }, children: "Navball" }),
67
- /* @__PURE__ */ jsxs("p", { style: {
68
- fontSize: tokens.typography.fontSize.xs,
69
- color: tokens.colors.text.tertiary,
70
- margin: 0,
71
- marginTop: tokens.spacing.xs
72
- }, children: [
73
- pointingMode ? pointingMode.charAt(0).toUpperCase() + pointingMode.slice(1).toLowerCase() : "Unknown",
74
- " pointing"
75
- ] })
76
- ] }),
77
- /* @__PURE__ */ jsxs("span", { style: {
78
- fontSize: tokens.typography.fontSize.xs,
79
- fontFamily: tokens.typography.fontFamily.mono,
80
- fontVariantNumeric: "tabular-nums",
81
- color: errorColor
82
- }, children: [
83
- "Δ ",
84
- pointingError.toFixed(2),
85
- "°"
86
- ] })
87
- ] }),
88
- /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsxs("div", { style: { position: "relative", ...sizeStyle }, children: [
89
- /* @__PURE__ */ jsxs("div", { style: {
90
- position: "absolute",
91
- inset: 0,
92
- borderRadius: "50%",
93
- border: `4px solid ${tokens.colors.border.muted}`,
94
- overflow: "hidden",
95
- backgroundColor: tokens.colors.background.base
96
- }, children: [
97
- /* @__PURE__ */ jsxs(
98
- "div",
99
- {
100
- style: {
101
- position: "absolute",
102
- inset: 0,
103
- transition: "transform 0.3s ease-out",
104
- ...horizonTransform
105
- },
106
- children: [
107
- /* @__PURE__ */ jsx(
108
- "div",
109
- {
110
- style: {
111
- position: "absolute",
112
- inset: "-50%",
113
- transformOrigin: "center",
114
- background: "linear-gradient(to bottom, #1e3a5f 0%, #1e3a5f 48%, #78350f 52%, #78350f 100%)"
115
- }
116
- }
117
- ),
118
- /* @__PURE__ */ jsxs("svg", { style: { position: "absolute", inset: 0, width: "100%", height: "100%", opacity: 0.2 }, viewBox: "0 0 100 100", children: [
119
- [-30, -15, 0, 15, 30].map((y) => /* @__PURE__ */ jsx("line", { x1: "0", y1: 50 + y, x2: "100", y2: 50 + y, stroke: "white", strokeWidth: "0.5" }, y)),
120
- /* @__PURE__ */ jsx("line", { x1: "50", y1: "0", x2: "50", y2: "100", stroke: "white", strokeWidth: "0.5" })
121
- ] })
122
- ]
123
- }
124
- ),
125
- /* @__PURE__ */ jsx(
126
- "div",
127
- {
128
- style: {
129
- position: "absolute",
130
- width: "24px",
131
- height: "24px",
132
- transform: "translate(-50%, -50%)",
133
- transition: "all 0.2s",
134
- top: `${50 - pitch * 0.8}%`,
135
- left: `${50 + yaw * 0.3}%`
136
- },
137
- children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", style: { width: "100%", height: "100%" }, children: [
138
- /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: statusColors.normal, strokeWidth: "2" }),
139
- /* @__PURE__ */ jsx("line", { x1: "12", y1: "4", x2: "12", y2: "8", stroke: statusColors.normal, strokeWidth: "2" }),
140
- /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12", y2: "20", stroke: statusColors.normal, strokeWidth: "2" }),
141
- /* @__PURE__ */ jsx("line", { x1: "4", y1: "12", x2: "8", y2: "12", stroke: statusColors.normal, strokeWidth: "2" }),
142
- /* @__PURE__ */ jsx("line", { x1: "16", y1: "12", x2: "20", y2: "12", stroke: statusColors.normal, strokeWidth: "2" })
143
- ] })
144
- }
145
- ),
146
- attitude.targetDirection && /* @__PURE__ */ jsx(
147
- "div",
148
- {
149
- style: {
150
- position: "absolute",
151
- width: "20px",
152
- height: "20px",
153
- transform: "translate(-50%, -50%)",
154
- top: "35%",
155
- left: "65%"
156
- },
157
- children: /* @__PURE__ */ jsx("div", { style: {
158
- width: "100%",
159
- height: "100%",
160
- border: `2px solid ${tokens.colors.accent.primary}`,
161
- borderRadius: "50%",
162
- display: "flex",
163
- alignItems: "center",
164
- justifyContent: "center"
165
- }, children: /* @__PURE__ */ jsx("div", { style: {
166
- width: "6px",
167
- height: "6px",
168
- backgroundColor: tokens.colors.accent.primary,
169
- borderRadius: "50%"
170
- } }) })
171
- }
172
- )
173
- ] }),
174
- /* @__PURE__ */ jsx("div", { style: {
175
- position: "absolute",
176
- inset: 0,
177
- display: "flex",
178
- alignItems: "center",
179
- justifyContent: "center",
180
- pointerEvents: "none"
181
- }, children: /* @__PURE__ */ jsx("div", { style: {
182
- color: statusColors.caution,
183
- fontSize: tokens.typography.fontSize.xxl,
184
- textShadow: `0 0 4px ${statusColors.caution}`
185
- }, children: "⨁" }) }),
186
- /* @__PURE__ */ jsxs(
187
- "svg",
188
- {
189
- style: { position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none" },
190
- viewBox: "0 0 100 100",
191
- children: [
192
- /* @__PURE__ */ jsx(
193
- "path",
194
- {
195
- d: "M 20 90 A 40 40 0 0 1 80 90",
196
- fill: "none",
197
- stroke: `${tokens.colors.text.tertiary}40`,
198
- strokeWidth: "2"
199
- }
200
- ),
201
- /* @__PURE__ */ jsx(
202
- "line",
203
- {
204
- x1: "50",
205
- y1: "85",
206
- x2: 50 + Math.sin(yaw * Math.PI / 180) * 25,
207
- y2: 90 - Math.cos(yaw * Math.PI / 180) * 10,
208
- stroke: tokens.colors.status.caution,
209
- strokeWidth: "2",
210
- strokeLinecap: "round"
211
- }
212
- )
213
- ]
214
- }
215
- )
216
- ] }) }),
217
- /* @__PURE__ */ jsxs("div", { style: {
218
- display: "flex",
219
- justifyContent: "space-between",
220
- marginTop: tokens.spacing.md,
221
- fontFamily: tokens.typography.fontFamily.mono,
222
- fontSize: compact ? "10px" : tokens.typography.fontSize.xs,
223
- fontVariantNumeric: "tabular-nums"
224
- }, children: [
225
- /* @__PURE__ */ jsx("span", { style: { color: statusColors.critical }, children: formatAngle(roll, "R") }),
226
- /* @__PURE__ */ jsx("span", { style: { color: statusColors.normal }, children: formatAngle(pitch, "P") }),
227
- /* @__PURE__ */ jsx("span", { style: { color: statusColors.standby }, children: formatAngle(yaw, "Y") })
228
- ] }),
229
- !compact && targetName && /* @__PURE__ */ jsx("div", { style: {
230
- marginTop: tokens.spacing.md,
231
- paddingTop: tokens.spacing.md,
232
- borderTop: `1px solid ${tokens.colors.border.muted}`,
233
- fontSize: tokens.typography.fontSize.xs
234
- }, children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
235
- /* @__PURE__ */ jsx("span", { style: { color: tokens.colors.text.tertiary }, children: "Target" }),
236
- /* @__PURE__ */ jsx("span", { style: { color: safeAccentText(tokens.colors.accent.primary) }, children: targetName })
237
- ] }) })
238
- ] });
239
- };
240
- export {
241
- NavBallCard
242
- };
243
- //# sourceMappingURL=NavBallCard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NavBallCard.js","sources":["../../../src/react/visualizations/NavBallCard.tsx"],"sourcesContent":["/**\n * NavBallCard - Attitude visualization (KSP-style NavBall)\n * \n * Visual sphere showing spacecraft orientation with markers for\n * prograde, normal, radial vectors and target alignment.\n * \n * Astro UX Compliance:\n * - Uses official Astro status colors via theme tokens\n * - Sentence-case labels\n * - Tabular numbers for data\n * - Roboto/Roboto Mono typography\n * - 4px-based spacing\n */\n\nimport React, { useMemo } from 'react';\nimport type { AttitudeData, PointingMode } from '../types';\nimport { useTheme } from '../theme';\nimport { safeAccentText, type StatusLevel } from '../utils';\n\nexport interface NavBallCardProps {\n /** Attitude data from API */\n attitude: AttitudeData;\n /** Current pointing mode */\n pointingMode?: PointingMode;\n /** Target name for display */\n targetName?: string;\n /** Compact mode */\n compact?: boolean;\n /** Custom class name */\n className?: string;\n}\n\nexport const NavBallCard: React.FC<NavBallCardProps> = ({\n attitude,\n pointingMode = 'nadir',\n targetName,\n compact = false,\n className = '',\n}) => {\n const { tokens, theme } = useTheme();\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n // Use transparent background with blur for transparent themes (matching Timeline)\n const cardBg = isTransparentTheme ? 'transparent' : tokens.colors.background.surface;\n const cardGlass = isTransparentTheme ? { \n backdropFilter: 'blur(12px)' as const, \n WebkitBackdropFilter: 'blur(12px)' as const,\n } : {};\n const { roll, pitch, yaw } = attitude.eulerAngles;\n const pointingError = attitude.pointingError ?? 0;\n\n // Calculate visual transforms\n const horizonTransform = useMemo(() => {\n const pitchClamp = Math.max(-45, Math.min(45, pitch));\n const rollClamp = Math.max(-180, Math.min(180, roll));\n return {\n transform: `rotate(${rollClamp}deg) translateY(${pitchClamp * 1.5}%)`,\n };\n }, [pitch, roll]);\n\n // Format angle for display (Astro: tabular numbers)\n const formatAngle = (angle: number, prefix: string): string => {\n const sign = angle >= 0 ? '+' : '';\n return `${prefix}: ${sign}${angle.toFixed(1)}°`;\n };\n\n // Medium-soft status colors (readable, not too pale)\n const statusColors: Record<StatusLevel, string> = {\n normal: '#6ed86e',\n caution: '#ffd54f',\n serious: '#ffa726',\n critical: '#e57373',\n off: '#90a4ae',\n standby: '#4fc3f7',\n };\n\n const errorColor = useMemo(() => {\n if (pointingError < 0.5) return statusColors.normal;\n if (pointingError < 2) return statusColors.caution;\n return statusColors.critical;\n }, [pointingError]);\n\n const sizeStyle: React.CSSProperties = compact \n ? { width: '96px', height: '96px' } \n : { width: '160px', height: '160px' };\n\n // Astro UX compliant card styling (transparent theme: glass background)\n const cardStyle: React.CSSProperties = {\n backgroundColor: cardBg,\n ...cardGlass,\n border: 'none',\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.md,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n };\n\n return (\n <div className={className} style={cardStyle}>\n {!compact && (\n <div style={{ \n display: 'flex', \n justifyContent: 'space-between', \n alignItems: 'center', \n marginBottom: tokens.spacing.md,\n }}>\n <div>\n {/* Astro: Sentence-case labels */}\n <h3 style={{ \n fontWeight: tokens.typography.fontWeight.medium, \n fontSize: tokens.typography.fontSize.md, \n color: tokens.colors.text.primary, \n margin: 0,\n }}>\n Navball\n </h3>\n <p style={{ \n fontSize: tokens.typography.fontSize.xs, \n color: tokens.colors.text.tertiary, \n margin: 0, \n marginTop: tokens.spacing.xs,\n }}>\n {pointingMode ? pointingMode.charAt(0).toUpperCase() + pointingMode.slice(1).toLowerCase() : 'Unknown'} pointing\n </p>\n </div>\n {/* Astro: Tabular numbers for data */}\n <span style={{ \n fontSize: tokens.typography.fontSize.xs, \n fontFamily: tokens.typography.fontFamily.mono, \n fontVariantNumeric: 'tabular-nums',\n color: errorColor,\n }}>\n Δ {pointingError.toFixed(2)}°\n </span>\n </div>\n )}\n\n <div style={{ display: 'flex', justifyContent: 'center' }}>\n <div style={{ position: 'relative', ...sizeStyle }}>\n {/* Outer ring */}\n <div style={{\n position: 'absolute',\n inset: 0,\n borderRadius: '50%',\n border: `4px solid ${tokens.colors.border.muted}`,\n overflow: 'hidden',\n backgroundColor: tokens.colors.background.base,\n }}>\n {/* Horizon gradient (day/night split) */}\n <div \n style={{\n position: 'absolute',\n inset: 0,\n transition: 'transform 0.3s ease-out',\n ...horizonTransform,\n }}\n >\n <div \n style={{\n position: 'absolute',\n inset: '-50%',\n transformOrigin: 'center',\n background: 'linear-gradient(to bottom, #1e3a5f 0%, #1e3a5f 48%, #78350f 52%, #78350f 100%)',\n }}\n />\n \n {/* Grid lines */}\n <svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', opacity: 0.2 }} viewBox=\"0 0 100 100\">\n {[-30, -15, 0, 15, 30].map(y => (\n <line key={y} x1=\"0\" y1={50 + y} x2=\"100\" y2={50 + y} stroke=\"white\" strokeWidth=\"0.5\" />\n ))}\n <line x1=\"50\" y1=\"0\" x2=\"50\" y2=\"100\" stroke=\"white\" strokeWidth=\"0.5\" />\n </svg>\n </div>\n\n {/* Prograde marker - uses Astro normal color */}\n <div \n style={{\n position: 'absolute',\n width: '24px',\n height: '24px',\n transform: 'translate(-50%, -50%)',\n transition: 'all 0.2s',\n top: `${50 - pitch * 0.8}%`, \n left: `${50 + yaw * 0.3}%`,\n }}\n >\n <svg viewBox=\"0 0 24 24\" style={{ width: '100%', height: '100%' }}>\n <circle cx=\"12\" cy=\"12\" r=\"8\" fill=\"none\" stroke={statusColors.normal} strokeWidth=\"2\" />\n <line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"8\" stroke={statusColors.normal} strokeWidth=\"2\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"20\" stroke={statusColors.normal} strokeWidth=\"2\" />\n <line x1=\"4\" y1=\"12\" x2=\"8\" y2=\"12\" stroke={statusColors.normal} strokeWidth=\"2\" />\n <line x1=\"16\" y1=\"12\" x2=\"20\" y2=\"12\" stroke={statusColors.normal} strokeWidth=\"2\" />\n </svg>\n </div>\n\n {/* Target marker (if aligned) */}\n {attitude.targetDirection && (\n <div \n style={{\n position: 'absolute',\n width: '20px',\n height: '20px',\n transform: 'translate(-50%, -50%)',\n top: '35%', \n left: '65%',\n }}\n >\n <div style={{\n width: '100%',\n height: '100%',\n border: `2px solid ${tokens.colors.accent.primary}`,\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}>\n <div style={{\n width: '6px',\n height: '6px',\n backgroundColor: tokens.colors.accent.primary,\n borderRadius: '50%',\n }} />\n </div>\n </div>\n )}\n </div>\n\n {/* Fixed crosshair (boresight) */}\n <div style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n pointerEvents: 'none',\n }}>\n <div style={{ \n color: statusColors.caution,\n fontSize: tokens.typography.fontSize.xxl,\n textShadow: `0 0 4px ${statusColors.caution}`,\n }}>⨁</div>\n </div>\n\n {/* Yaw indicator arc */}\n <svg \n style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }} \n viewBox=\"0 0 100 100\"\n >\n <path\n d=\"M 20 90 A 40 40 0 0 1 80 90\"\n fill=\"none\"\n stroke={`${tokens.colors.text.tertiary}40`}\n strokeWidth=\"2\"\n />\n {/* Yaw needle */}\n <line\n x1=\"50\"\n y1=\"85\"\n x2={50 + Math.sin(yaw * Math.PI / 180) * 25}\n y2={90 - Math.cos(yaw * Math.PI / 180) * 10}\n stroke={tokens.colors.status.caution}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n </div>\n\n {/* Attitude readouts - Astro: tabular numbers */}\n <div style={{ \n display: 'flex', \n justifyContent: 'space-between', \n marginTop: tokens.spacing.md,\n fontFamily: tokens.typography.fontFamily.mono,\n fontSize: compact ? '10px' : tokens.typography.fontSize.xs,\n fontVariantNumeric: 'tabular-nums',\n }}>\n <span style={{ color: statusColors.critical }}>{formatAngle(roll, 'R')}</span>\n <span style={{ color: statusColors.normal }}>{formatAngle(pitch, 'P')}</span>\n <span style={{ color: statusColors.standby }}>{formatAngle(yaw, 'Y')}</span>\n </div>\n\n {/* Target info - Astro: Sentence-case */}\n {!compact && targetName && (\n <div style={{\n marginTop: tokens.spacing.md,\n paddingTop: tokens.spacing.md,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n fontSize: tokens.typography.fontSize.xs,\n }}>\n <div style={{ display: 'flex', justifyContent: 'space-between' }}>\n <span style={{ color: tokens.colors.text.tertiary }}>Target</span>\n <span style={{ color: safeAccentText(tokens.colors.accent.primary) }}>{targetName}</span>\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default NavBallCard;\n\n\n\n\n"],"names":[],"mappings":"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"}
@@ -1,298 +0,0 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { memo, useMemo } from "react";
3
- import { AstroIcon } from "../core/AstroIcon.js";
4
- import { classNames, safeNumber, formatPercentage } from "../utils/index.js";
5
- import { useTheme } from "../theme/ThemeProvider.js";
6
- function getPercentageStatus(pct) {
7
- if (pct === void 0 || !Number.isFinite(pct)) return "off";
8
- if (pct > 50) return "normal";
9
- if (pct > 20) return "caution";
10
- if (pct > 5) return "serious";
11
- return "critical";
12
- }
13
- const PropulsionCard = memo(function PropulsionCard2({
14
- tanks,
15
- remainingDeltaVMs,
16
- totalDeltaVMs,
17
- ispSeconds,
18
- maneuvers = [],
19
- compact = false,
20
- loading = false,
21
- className = ""
22
- }) {
23
- const { tokens, theme, prefersReducedMotion } = useTheme();
24
- const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
25
- const cardBg = isTransparentTheme ? "transparent" : tokens.colors.background.surface;
26
- const cardGlass = isTransparentTheme ? {
27
- backdropFilter: "blur(12px)",
28
- WebkitBackdropFilter: "blur(12px)"
29
- } : {};
30
- const transitionDuration = prefersReducedMotion ? "0ms" : "300ms";
31
- const statusColors = {
32
- normal: "#6ed86e",
33
- caution: "#ffd54f",
34
- serious: "#ffa726",
35
- critical: "#e57373",
36
- off: "#90a4ae",
37
- standby: "#4fc3f7"
38
- };
39
- useMemo(() => {
40
- if (!tanks || tanks.length === 0) return 0;
41
- const totalCurrent = tanks.reduce((sum, t) => sum + (t.currentMassKg ?? 0), 0);
42
- const totalMax = tanks.reduce((sum, t) => sum + (t.maxMassKg ?? 0), 0);
43
- return totalMax > 0 ? totalCurrent / totalMax * 100 : 0;
44
- }, [tanks]);
45
- const deltaVPercentage = useMemo(() => {
46
- const total = totalDeltaVMs ?? 0;
47
- const remaining = remainingDeltaVMs ?? 0;
48
- return total > 0 ? remaining / total * 100 : 0;
49
- }, [remainingDeltaVMs, totalDeltaVMs]);
50
- const deltaVStatus = getPercentageStatus(deltaVPercentage);
51
- const deltaVColor = statusColors[deltaVStatus] || statusColors.off;
52
- const getPercentageColor = (pct) => {
53
- const status = getPercentageStatus(pct);
54
- return statusColors[status] || statusColors.off;
55
- };
56
- if (loading) {
57
- return /* @__PURE__ */ jsxs(
58
- "div",
59
- {
60
- className: classNames("zendir-propulsion-card", "loading", className),
61
- role: "article",
62
- "aria-busy": "true",
63
- "aria-label": "Loading propulsion data",
64
- style: {
65
- backgroundColor: cardBg,
66
- ...cardGlass,
67
- border: "none",
68
- borderRadius: tokens.borderRadius.lg,
69
- padding: tokens.spacing.md,
70
- minHeight: 180
71
- },
72
- children: [
73
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: 16 }, children: [
74
- /* @__PURE__ */ jsx("div", { style: { height: 24, width: "40%", backgroundColor: "rgba(255,255,255,0.1)", borderRadius: 4 } }),
75
- /* @__PURE__ */ jsx("div", { style: { height: 24, width: 80, backgroundColor: "rgba(255,255,255,0.1)", borderRadius: 4 } })
76
- ] }),
77
- /* @__PURE__ */ jsx("div", { style: { height: 12, backgroundColor: "rgba(255,255,255,0.06)", borderRadius: 4, marginBottom: 16 } }),
78
- [1, 2].map((i) => /* @__PURE__ */ jsx("div", { style: { height: 32, backgroundColor: "rgba(255,255,255,0.06)", borderRadius: 4, marginBottom: 8 } }, i))
79
- ]
80
- }
81
- );
82
- }
83
- if (!tanks || tanks.length === 0) {
84
- return /* @__PURE__ */ jsxs(
85
- "div",
86
- {
87
- className: classNames("zendir-propulsion-card", "empty", className),
88
- role: "article",
89
- "aria-label": "No propulsion data",
90
- style: {
91
- backgroundColor: cardBg,
92
- ...cardGlass,
93
- border: "none",
94
- borderRadius: tokens.borderRadius.lg,
95
- padding: tokens.spacing.lg,
96
- textAlign: "center",
97
- color: tokens.colors.text.tertiary
98
- },
99
- children: [
100
- /* @__PURE__ */ jsx(AstroIcon, { name: "launch", size: "normal", label: "", style: { opacity: 0.5 } }),
101
- /* @__PURE__ */ jsx("p", { style: { margin: "8px 0 0 0", fontSize: tokens.typography.body[2].fontSize }, children: "No propulsion data available" })
102
- ]
103
- }
104
- );
105
- }
106
- const getTankIconName = (type) => {
107
- switch (type) {
108
- case "hydrazine":
109
- return "propulsion-power";
110
- case "xenon":
111
- return "cloud";
112
- case "cold_gas":
113
- return "ac-unit";
114
- case "bipropellant":
115
- return "whatshot";
116
- default:
117
- return "propulsion-power";
118
- }
119
- };
120
- const cardStyle = {
121
- backgroundColor: cardBg,
122
- ...isTransparentTheme && { backdropFilter: "blur(12px)", WebkitBackdropFilter: "blur(12px)" },
123
- border: "none",
124
- borderRadius: tokens.borderRadius.lg,
125
- padding: tokens.spacing.md,
126
- fontFamily: tokens.typography.fontFamily.primary,
127
- color: tokens.colors.text.primary
128
- };
129
- const labelStyle = {
130
- color: tokens.colors.text.tertiary,
131
- fontSize: tokens.typography.fontSize.xs,
132
- fontWeight: tokens.typography.fontWeight.medium
133
- };
134
- return /* @__PURE__ */ jsxs(
135
- "article",
136
- {
137
- className: classNames("zendir-propulsion-card", className),
138
- "aria-label": "Propulsion system status",
139
- style: cardStyle,
140
- children: [
141
- !compact && /* @__PURE__ */ jsxs("div", { style: {
142
- display: "flex",
143
- justifyContent: "space-between",
144
- alignItems: "center",
145
- marginBottom: tokens.spacing.md
146
- }, children: [
147
- /* @__PURE__ */ jsxs("div", { children: [
148
- /* @__PURE__ */ jsx("h3", { style: {
149
- fontWeight: tokens.typography.fontWeight.medium,
150
- fontSize: tokens.typography.fontSize.md,
151
- color: tokens.colors.text.primary,
152
- margin: 0
153
- }, children: "Propulsion" }),
154
- /* @__PURE__ */ jsx("p", { style: {
155
- fontSize: tokens.typography.fontSize.xs,
156
- color: tokens.colors.text.tertiary,
157
- margin: 0,
158
- marginTop: tokens.spacing.xs
159
- }, children: ispSeconds ? `Isp: ${ispSeconds}s` : "Delta-V budget" })
160
- ] }),
161
- /* @__PURE__ */ jsxs("span", { style: {
162
- fontSize: tokens.typography.fontSize.lg,
163
- fontWeight: tokens.typography.fontWeight.bold,
164
- fontFamily: tokens.typography.fontFamily.mono,
165
- fontVariantNumeric: "tabular-nums",
166
- color: deltaVColor
167
- }, children: [
168
- safeNumber(remainingDeltaVMs, 0),
169
- " m/s"
170
- ] })
171
- ] }),
172
- /* @__PURE__ */ jsxs("div", { style: { marginBottom: tokens.spacing.md }, children: [
173
- /* @__PURE__ */ jsxs("div", { style: {
174
- display: "flex",
175
- justifyContent: "space-between",
176
- fontSize: tokens.typography.fontSize.xs,
177
- marginBottom: tokens.spacing.xs
178
- }, children: [
179
- /* @__PURE__ */ jsx("span", { style: labelStyle, children: "Remaining ΔV" }),
180
- /* @__PURE__ */ jsx("span", { style: {
181
- fontFamily: tokens.typography.fontFamily.mono,
182
- color: deltaVColor
183
- }, children: formatPercentage(deltaVPercentage, false, 0) })
184
- ] }),
185
- /* @__PURE__ */ jsx("div", { style: {
186
- height: "12px",
187
- backgroundColor: tokens.colors.border.muted,
188
- borderRadius: tokens.borderRadius.sm,
189
- overflow: "hidden"
190
- }, children: /* @__PURE__ */ jsx("div", { style: {
191
- height: "100%",
192
- width: `${Math.min(100, Math.max(0, deltaVPercentage))}%`,
193
- backgroundColor: deltaVColor,
194
- transition: `width ${transitionDuration} ease`,
195
- borderRadius: tokens.borderRadius.sm
196
- } }) }),
197
- /* @__PURE__ */ jsxs("div", { style: {
198
- display: "flex",
199
- justifyContent: "space-between",
200
- fontSize: tokens.typography.fontSize.xxs,
201
- // 0.625rem / 10px (AstroUXDS compact)
202
- color: tokens.colors.text.tertiary,
203
- marginTop: tokens.spacing.xs
204
- }, children: [
205
- /* @__PURE__ */ jsx("span", { children: "0" }),
206
- /* @__PURE__ */ jsxs("span", { children: [
207
- safeNumber(totalDeltaVMs, 0),
208
- " m/s"
209
- ] })
210
- ] })
211
- ] }),
212
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: tokens.spacing.sm, marginBottom: tokens.spacing.md }, children: tanks.map((tank) => {
213
- const current = tank.currentMassKg ?? 0;
214
- const max = tank.maxMassKg ?? 1;
215
- const pct = max > 0 ? current / max * 100 : 0;
216
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.sm }, children: [
217
- /* @__PURE__ */ jsx(AstroIcon, { name: getTankIconName(tank.type), size: "small", label: tank.type, style: { fontSize: tokens.typography.fontSize.sm } }),
218
- /* @__PURE__ */ jsxs("div", { style: { flex: 1 }, children: [
219
- /* @__PURE__ */ jsxs("div", { style: {
220
- display: "flex",
221
- justifyContent: "space-between",
222
- fontSize: tokens.typography.fontSize.xs,
223
- // 0.75rem / 12px (AstroUXDS body3)
224
- marginBottom: "2px"
225
- }, children: [
226
- /* @__PURE__ */ jsx("span", { style: { color: tokens.colors.text.secondary }, children: tank.name }),
227
- /* @__PURE__ */ jsxs("span", { style: {
228
- fontFamily: tokens.typography.fontFamily.mono,
229
- color: tokens.colors.text.tertiary,
230
- fontVariantNumeric: "tabular-nums"
231
- }, children: [
232
- safeNumber(current, 1),
233
- " / ",
234
- safeNumber(max, 1),
235
- " kg"
236
- ] })
237
- ] }),
238
- /* @__PURE__ */ jsx("div", { style: {
239
- height: "6px",
240
- backgroundColor: tokens.colors.border.muted,
241
- borderRadius: tokens.borderRadius.sm,
242
- overflow: "hidden"
243
- }, children: /* @__PURE__ */ jsx("div", { style: {
244
- height: "100%",
245
- width: `${pct}%`,
246
- backgroundColor: getPercentageColor(pct),
247
- borderRadius: tokens.borderRadius.sm
248
- } }) })
249
- ] })
250
- ] }, tank.id);
251
- }) }),
252
- maneuvers.length > 0 && !compact && /* @__PURE__ */ jsxs("div", { style: {
253
- paddingTop: tokens.spacing.md,
254
- borderTop: `1px solid ${tokens.colors.border.muted}`
255
- }, children: [
256
- /* @__PURE__ */ jsx("div", { style: {
257
- ...labelStyle,
258
- marginBottom: tokens.spacing.sm
259
- }, children: "Maneuver feasibility" }),
260
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: tokens.spacing.xs }, children: maneuvers.map((m, i) => /* @__PURE__ */ jsxs("div", { style: {
261
- display: "flex",
262
- alignItems: "center",
263
- justifyContent: "space-between",
264
- fontSize: tokens.typography.fontSize.xs
265
- }, children: [
266
- /* @__PURE__ */ jsx("span", { style: { color: tokens.colors.text.secondary }, children: m.name }),
267
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.sm }, children: [
268
- /* @__PURE__ */ jsxs("span", { style: {
269
- fontFamily: tokens.typography.fontFamily.mono,
270
- color: tokens.colors.text.tertiary
271
- }, children: [
272
- m.requiredDeltaVMs,
273
- " m/s"
274
- ] }),
275
- /* @__PURE__ */ jsx("span", { style: {
276
- fontWeight: tokens.typography.fontWeight.bold,
277
- color: m.feasible ? tokens.colors.status.normal : tokens.colors.status.critical
278
- }, children: m.feasible ? "✓" : "✗" })
279
- ] })
280
- ] }, i)) })
281
- ] }),
282
- deltaVPercentage < 20 && /* @__PURE__ */ jsx("div", { style: {
283
- marginTop: tokens.spacing.md,
284
- padding: tokens.spacing.sm,
285
- backgroundColor: `${tokens.colors.status.critical}15`,
286
- border: `1px solid ${tokens.colors.status.critical}40`,
287
- borderRadius: tokens.borderRadius.md,
288
- fontSize: tokens.typography.fontSize.xs,
289
- color: tokens.colors.status.critical
290
- }, children: "⚠️ Low propellant - limit maneuvers" })
291
- ]
292
- }
293
- );
294
- });
295
- export {
296
- PropulsionCard
297
- };
298
- //# sourceMappingURL=PropulsionCard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PropulsionCard.js","sources":["../../../src/react/visualizations/PropulsionCard.tsx"],"sourcesContent":["/**\n * @zendir/ui - PropulsionCard Component\n * \n * Delta-V Budget and Fuel Status visualization.\n * Shows propellant levels and remaining delta-V capability.\n * \n * Features:\n * - Full null-safety with graceful fallbacks\n * - Tank level visualization\n * - Maneuver feasibility checks\n * - Loading and empty states\n */\n\nimport React, { memo, useMemo } from 'react';\nimport { useTheme } from '../theme';\nimport { AstroIcon, type AstroIconName } from '../core/AstroIcon';\nimport {\n safeNumber,\n formatPercentage,\n classNames,\n type StatusLevel,\n} from '../utils';\n\nexport interface PropulsionTankData {\n id: string;\n name: string;\n /** Current mass in kg */\n currentMassKg: number;\n /** Maximum capacity in kg */\n maxMassKg: number;\n /** Propellant type */\n type: 'hydrazine' | 'xenon' | 'cold_gas' | 'bipropellant' | string;\n}\n\nexport interface ManeuverFeasibility {\n name: string;\n requiredDeltaVMs: number;\n feasible: boolean;\n}\n\nexport interface PropulsionCardProps {\n /** Propellant tanks data */\n tanks?: PropulsionTankData[];\n /** Remaining delta-V in m/s */\n remainingDeltaVMs?: number;\n /** Total delta-V at full tanks in m/s */\n totalDeltaVMs?: number;\n /** Specific impulse in seconds */\n ispSeconds?: number;\n /** Common maneuvers with feasibility */\n maneuvers?: ManeuverFeasibility[];\n /** Compact mode */\n compact?: boolean;\n /** Loading state */\n loading?: boolean;\n /** Custom class name */\n className?: string;\n}\n\n/**\n * Get status level based on percentage\n */\nfunction getPercentageStatus(pct: number | undefined): StatusLevel {\n if (pct === undefined || !Number.isFinite(pct)) return 'off';\n if (pct > 50) return 'normal';\n if (pct > 20) return 'caution';\n if (pct > 5) return 'serious';\n return 'critical';\n}\n\nexport const PropulsionCard = memo(function PropulsionCard({\n tanks,\n remainingDeltaVMs,\n totalDeltaVMs,\n ispSeconds,\n maneuvers = [],\n compact = false,\n loading = false,\n className = '',\n}: PropulsionCardProps): React.ReactElement {\n const { tokens, theme, prefersReducedMotion } = useTheme();\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n // Use transparent background with blur for transparent themes (matching Timeline)\n const cardBg = isTransparentTheme ? 'transparent' : tokens.colors.background.surface;\n const cardGlass = isTransparentTheme ? { \n backdropFilter: 'blur(12px)' as const, \n WebkitBackdropFilter: 'blur(12px)' as const,\n } : {};\n\n const transitionDuration = prefersReducedMotion ? '0ms' : '300ms';\n // Medium-soft status colors (readable, not too pale)\n const statusColors: Record<StatusLevel, string> = {\n normal: '#6ed86e',\n caution: '#ffd54f',\n serious: '#ffa726',\n critical: '#e57373',\n off: '#90a4ae',\n standby: '#4fc3f7',\n };\n\n // Calculate overall propellant percentage\n const _overallPercentage = useMemo(() => {\n if (!tanks || tanks.length === 0) return 0;\n const totalCurrent = tanks.reduce((sum, t) => sum + (t.currentMassKg ?? 0), 0);\n const totalMax = tanks.reduce((sum, t) => sum + (t.maxMassKg ?? 0), 0);\n return totalMax > 0 ? (totalCurrent / totalMax) * 100 : 0;\n }, [tanks]);\n\n // Delta-V percentage\n const deltaVPercentage = useMemo(() => {\n const total = totalDeltaVMs ?? 0;\n const remaining = remainingDeltaVMs ?? 0;\n return total > 0 ? (remaining / total) * 100 : 0;\n }, [remainingDeltaVMs, totalDeltaVMs]);\n\n const deltaVStatus = getPercentageStatus(deltaVPercentage);\n const deltaVColor = statusColors[deltaVStatus] || statusColors.off;\n\n // Get color based on percentage\n const getPercentageColor = (pct: number | undefined): string => {\n const status = getPercentageStatus(pct);\n return statusColors[status as keyof typeof statusColors] || statusColors.off;\n };\n\n // Loading state\n if (loading) {\n return (\n <div\n className={classNames('zendir-propulsion-card', 'loading', className)}\n role=\"article\"\n aria-busy=\"true\"\n aria-label=\"Loading propulsion data\"\n style={{\n backgroundColor: cardBg,\n ...cardGlass,\n border: 'none',\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.md,\n minHeight: 180,\n }}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>\n <div style={{ height: 24, width: '40%', backgroundColor: 'rgba(255,255,255,0.1)', borderRadius: 4 }} />\n <div style={{ height: 24, width: 80, backgroundColor: 'rgba(255,255,255,0.1)', borderRadius: 4 }} />\n </div>\n <div style={{ height: 12, backgroundColor: 'rgba(255,255,255,0.06)', borderRadius: 4, marginBottom: 16 }} />\n {[1, 2].map((i) => (\n <div key={i} style={{ height: 32, backgroundColor: 'rgba(255,255,255,0.06)', borderRadius: 4, marginBottom: 8 }} />\n ))}\n </div>\n );\n }\n\n // Empty state\n if (!tanks || tanks.length === 0) {\n return (\n <div\n className={classNames('zendir-propulsion-card', 'empty', className)}\n role=\"article\"\n aria-label=\"No propulsion data\"\n style={{\n backgroundColor: cardBg,\n ...cardGlass,\n border: 'none',\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.lg,\n textAlign: 'center',\n color: tokens.colors.text.tertiary,\n }}\n >\n <AstroIcon name=\"launch\" size=\"normal\" label=\"\" style={{ opacity: 0.5 }} />\n <p style={{ margin: '8px 0 0 0', fontSize: tokens.typography.body[2].fontSize }}>No propulsion data available</p>\n </div>\n );\n }\n\n // Tank type icons (AstroIcon)\n const getTankIconName = (type: string): AstroIconName => {\n switch (type) {\n case 'hydrazine': return 'propulsion-power';\n case 'xenon': return 'cloud';\n case 'cold_gas': return 'ac-unit';\n case 'bipropellant': return 'whatshot';\n default: return 'propulsion-power';\n }\n };\n\n // Astro UX compliant card styling (transparent theme: glass background)\n const cardStyle: React.CSSProperties = {\n backgroundColor: cardBg,\n ...(isTransparentTheme && { backdropFilter: 'blur(12px)' as const, WebkitBackdropFilter: 'blur(12px)' as const }),\n border: 'none',\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.md,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n };\n\n // Sentence-case label style (Astro guideline)\n const labelStyle: React.CSSProperties = {\n color: tokens.colors.text.tertiary,\n fontSize: tokens.typography.fontSize.xs,\n fontWeight: tokens.typography.fontWeight.medium,\n };\n\n return (\n <article\n className={classNames('zendir-propulsion-card', className)}\n aria-label=\"Propulsion system status\"\n style={cardStyle}\n >\n {!compact && (\n <div style={{ \n display: 'flex', \n justifyContent: 'space-between', \n alignItems: 'center', \n marginBottom: tokens.spacing.md,\n }}>\n <div>\n {/* Astro: Sentence-case labels */}\n <h3 style={{ \n fontWeight: tokens.typography.fontWeight.medium, \n fontSize: tokens.typography.fontSize.md, \n color: tokens.colors.text.primary, \n margin: 0,\n }}>\n Propulsion\n </h3>\n <p style={{ \n fontSize: tokens.typography.fontSize.xs, \n color: tokens.colors.text.tertiary, \n margin: 0,\n marginTop: tokens.spacing.xs,\n }}>\n {ispSeconds ? `Isp: ${ispSeconds}s` : 'Delta-V budget'}\n </p>\n </div>\n {/* Astro: Tabular numbers for data */}\n <span style={{ \n fontSize: tokens.typography.fontSize.lg, \n fontWeight: tokens.typography.fontWeight.bold,\n fontFamily: tokens.typography.fontFamily.mono, \n fontVariantNumeric: 'tabular-nums',\n color: deltaVColor,\n }}>\n {safeNumber(remainingDeltaVMs, 0)} m/s\n </span>\n </div>\n )}\n\n {/* Delta-V gauge */}\n <div style={{ marginBottom: tokens.spacing.md }}>\n <div style={{ \n display: 'flex', \n justifyContent: 'space-between', \n fontSize: tokens.typography.fontSize.xs, \n marginBottom: tokens.spacing.xs,\n }}>\n <span style={labelStyle}>Remaining ΔV</span>\n <span style={{ \n fontFamily: tokens.typography.fontFamily.mono,\n color: deltaVColor,\n }}>\n {formatPercentage(deltaVPercentage, false, 0)}\n </span>\n </div>\n <div style={{\n height: '12px',\n backgroundColor: tokens.colors.border.muted,\n borderRadius: tokens.borderRadius.sm,\n overflow: 'hidden',\n }}>\n <div style={{\n height: '100%',\n width: `${Math.min(100, Math.max(0, deltaVPercentage))}%`,\n backgroundColor: deltaVColor,\n transition: `width ${transitionDuration} ease`,\n borderRadius: tokens.borderRadius.sm,\n }} />\n </div>\n <div style={{ \n display: 'flex', \n justifyContent: 'space-between', \n fontSize: tokens.typography.fontSize.xxs, // 0.625rem / 10px (AstroUXDS compact)\n color: tokens.colors.text.tertiary, \n marginTop: tokens.spacing.xs,\n }}>\n <span>0</span>\n <span>{safeNumber(totalDeltaVMs, 0)} m/s</span>\n </div>\n </div>\n\n {/* Tank levels */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: tokens.spacing.sm, marginBottom: tokens.spacing.md }}>\n {tanks.map((tank) => {\n const current = tank.currentMassKg ?? 0;\n const max = tank.maxMassKg ?? 1;\n const pct = max > 0 ? (current / max) * 100 : 0;\n return (\n <div key={tank.id} style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.sm }}>\n <AstroIcon name={getTankIconName(tank.type)} size=\"small\" label={tank.type} style={{ fontSize: tokens.typography.fontSize.sm }} />\n <div style={{ flex: 1 }}>\n <div style={{ \n display: 'flex', \n justifyContent: 'space-between', \n fontSize: tokens.typography.fontSize.xs, // 0.75rem / 12px (AstroUXDS body3)\n marginBottom: '2px',\n }}>\n <span style={{ color: tokens.colors.text.secondary }}>{tank.name}</span>\n <span style={{ \n fontFamily: tokens.typography.fontFamily.mono, \n color: tokens.colors.text.tertiary,\n fontVariantNumeric: 'tabular-nums',\n }}>\n {safeNumber(current, 1)} / {safeNumber(max, 1)} kg\n </span>\n </div>\n <div style={{\n height: '6px',\n backgroundColor: tokens.colors.border.muted,\n borderRadius: tokens.borderRadius.sm,\n overflow: 'hidden',\n }}>\n <div style={{\n height: '100%',\n width: `${pct}%`,\n backgroundColor: getPercentageColor(pct),\n borderRadius: tokens.borderRadius.sm,\n }} />\n </div>\n </div>\n </div>\n );\n })}\n </div>\n\n {/* Maneuver feasibility - Astro: Sentence-case */}\n {maneuvers.length > 0 && !compact && (\n <div style={{\n paddingTop: tokens.spacing.md,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n }}>\n <div style={{ \n ...labelStyle, \n marginBottom: tokens.spacing.sm,\n }}>\n Maneuver feasibility\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: tokens.spacing.xs }}>\n {maneuvers.map((m, i) => (\n <div key={i} style={{ \n display: 'flex', \n alignItems: 'center', \n justifyContent: 'space-between', \n fontSize: tokens.typography.fontSize.xs,\n }}>\n <span style={{ color: tokens.colors.text.secondary }}>{m.name}</span>\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.sm }}>\n <span style={{ \n fontFamily: tokens.typography.fontFamily.mono, \n color: tokens.colors.text.tertiary,\n }}>\n {m.requiredDeltaVMs} m/s\n </span>\n <span style={{ \n fontWeight: tokens.typography.fontWeight.bold,\n color: m.feasible ? tokens.colors.status.normal : tokens.colors.status.critical,\n }}>\n {m.feasible ? '✓' : '✗'}\n </span>\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Warning if low - Astro notification style */}\n {deltaVPercentage < 20 && (\n <div style={{\n marginTop: tokens.spacing.md,\n padding: tokens.spacing.sm,\n backgroundColor: `${tokens.colors.status.critical}15`,\n border: `1px solid ${tokens.colors.status.critical}40`,\n borderRadius: tokens.borderRadius.md,\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.status.critical,\n }}>\n ⚠️ Low propellant - limit maneuvers\n </div>\n )}\n </article>\n );\n});\n\nexport default PropulsionCard;\n\n\n\n\n"],"names":["PropulsionCard"],"mappings":"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"}