@buoy-gg/storage 7.0.7 → 7.0.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 (42) hide show
  1. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +1 -1
  2. package/package.json +5 -5
  3. package/lib/commonjs/storage/components/GameUIStorageStats.js +0 -746
  4. package/lib/commonjs/storage/components/StorageActions.js +0 -178
  5. package/lib/commonjs/storage/components/StorageEventListener.js +0 -357
  6. package/lib/commonjs/storage/components/StorageFilterViewV2.js +0 -42
  7. package/lib/commonjs/storage/hooks/useMeasuredWidth.js +0 -74
  8. package/lib/commonjs/storage/hooks/useTickEverySecond.js +0 -21
  9. package/lib/commonjs/storage/index.js +0 -258
  10. package/lib/commonjs/storage/utils/index.js +0 -230
  11. package/lib/commonjs/storage/utils/objectDiff.js +0 -157
  12. package/lib/commonjs/storage/utils/safeAsyncStorage.js +0 -140
  13. package/lib/module/storage/components/GameUIStorageStats.js +0 -743
  14. package/lib/module/storage/components/StorageActions.js +0 -174
  15. package/lib/module/storage/components/StorageEventListener.js +0 -354
  16. package/lib/module/storage/components/StorageFilterViewV2.js +0 -38
  17. package/lib/module/storage/hooks/useMeasuredWidth.js +0 -71
  18. package/lib/module/storage/hooks/useTickEverySecond.js +0 -18
  19. package/lib/module/storage/index.js +0 -34
  20. package/lib/module/storage/utils/index.js +0 -28
  21. package/lib/module/storage/utils/objectDiff.js +0 -153
  22. package/lib/module/storage/utils/safeAsyncStorage.js +0 -134
  23. package/lib/typescript/storage/components/GameUIStorageStats.d.ts +0 -7
  24. package/lib/typescript/storage/components/GameUIStorageStats.d.ts.map +0 -1
  25. package/lib/typescript/storage/components/StorageActions.d.ts +0 -10
  26. package/lib/typescript/storage/components/StorageActions.d.ts.map +0 -1
  27. package/lib/typescript/storage/components/StorageEventListener.d.ts +0 -6
  28. package/lib/typescript/storage/components/StorageEventListener.d.ts.map +0 -1
  29. package/lib/typescript/storage/components/StorageFilterViewV2.d.ts +0 -9
  30. package/lib/typescript/storage/components/StorageFilterViewV2.d.ts.map +0 -1
  31. package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts +0 -37
  32. package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts.map +0 -1
  33. package/lib/typescript/storage/hooks/useTickEverySecond.d.ts +0 -6
  34. package/lib/typescript/storage/hooks/useTickEverySecond.d.ts.map +0 -1
  35. package/lib/typescript/storage/index.d.ts +0 -21
  36. package/lib/typescript/storage/index.d.ts.map +0 -1
  37. package/lib/typescript/storage/utils/index.d.ts +0 -10
  38. package/lib/typescript/storage/utils/index.d.ts.map +0 -1
  39. package/lib/typescript/storage/utils/objectDiff.d.ts +0 -35
  40. package/lib/typescript/storage/utils/objectDiff.d.ts.map +0 -1
  41. package/lib/typescript/storage/utils/safeAsyncStorage.d.ts +0 -56
  42. package/lib/typescript/storage/utils/safeAsyncStorage.d.ts.map +0 -1
@@ -1,746 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.GameUIStorageStats = GameUIStorageStats;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _jsxRuntime = require("react/jsx-runtime");
11
- // Use macOS colors
12
- const gameColors = {
13
- ..._sharedUi.gameUIColors,
14
- ..._sharedUi.macOSColors.semantic,
15
- primary: _sharedUi.macOSColors.text.primary,
16
- secondary: _sharedUi.macOSColors.text.secondary,
17
- muted: _sharedUi.macOSColors.text.muted,
18
- panel: _sharedUi.macOSColors.background.card,
19
- border: _sharedUi.macOSColors.border.default,
20
- online: _sharedUi.macOSColors.semantic.success,
21
- storage: _sharedUi.macOSColors.semantic.debug,
22
- optional: _sharedUi.macOSColors.semantic.debug
23
- };
24
-
25
- // Storage type configurations with game UI colors
26
- const storageTypeData = [{
27
- key: "valid",
28
- label: "VALID KEYS",
29
- subtitle: "Stored correctly",
30
- icon: _sharedUi.CheckCircle2,
31
- color: gameColors.online
32
- }, {
33
- key: "missing",
34
- label: "MISSING KEYS",
35
- subtitle: "Required but absent",
36
- icon: _sharedUi.AlertCircle,
37
- color: gameColors.error
38
- }, {
39
- key: "wrongValue",
40
- label: "VALUE ERROR",
41
- subtitle: "Incorrect data",
42
- icon: _sharedUi.XCircle,
43
- color: gameColors.warning
44
- }, {
45
- key: "wrongType",
46
- label: "TYPE ERROR",
47
- subtitle: "Wrong format",
48
- icon: _sharedUi.Zap,
49
- color: gameColors.info
50
- }, {
51
- key: "optional",
52
- label: "AUXILIARY DATA",
53
- subtitle: "Optional storage",
54
- icon: _sharedUi.Eye,
55
- color: gameColors.optional
56
- }];
57
-
58
- // Storage backend types
59
- const backendTypeData = [{
60
- key: "mmkv",
61
- label: "MMKV",
62
- subtitle: "High-speed memory",
63
- icon: _sharedUi.Zap,
64
- color: gameColors.info
65
- }, {
66
- key: "async",
67
- label: "ASYNC STORAGE",
68
- subtitle: "Standard persistence",
69
- icon: _sharedUi.Database,
70
- color: gameColors.storage
71
- }, {
72
- key: "secure",
73
- label: "SECURE VAULT",
74
- subtitle: "Encrypted storage",
75
- icon: _sharedUi.Shield,
76
- color: gameColors.online
77
- }];
78
- function GameUIStorageStats({
79
- stats
80
- }) {
81
- const {
82
- totalCount,
83
- missingCount,
84
- wrongValueCount,
85
- wrongTypeCount,
86
- presentRequiredCount,
87
- optionalCount,
88
- mmkvCount,
89
- asyncCount,
90
- secureCount
91
- } = stats;
92
-
93
- // Minimal animation values - only for status indicator
94
- const statusPulse = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
95
- (0, _react.useEffect)(() => {
96
- // Simple status pulse for critical states only
97
- if (missingCount > 0 || wrongValueCount > 0 || wrongTypeCount > 0) {
98
- _reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(statusPulse, {
99
- toValue: 1,
100
- duration: 1500,
101
- useNativeDriver: true
102
- }), _reactNative.Animated.timing(statusPulse, {
103
- toValue: 0.6,
104
- duration: 1500,
105
- useNativeDriver: true
106
- })])).start();
107
- } else {
108
- _reactNative.Animated.timing(statusPulse, {
109
- toValue: 1,
110
- duration: 300,
111
- useNativeDriver: true
112
- }).start();
113
- }
114
- }, [missingCount, wrongValueCount, wrongTypeCount, statusPulse]);
115
- const statusPulseStyle = {
116
- opacity: statusPulse
117
- };
118
-
119
- // Calculate storage health
120
- const requiredTotal = presentRequiredCount + missingCount + wrongValueCount + wrongTypeCount;
121
- const healthPercentage = requiredTotal > 0 ? Math.round(presentRequiredCount / requiredTotal * 100) : 100;
122
- const healthStatus = healthPercentage >= 90 ? "OPTIMAL" : healthPercentage >= 70 ? "WARNING" : "CRITICAL";
123
- const healthColor = healthPercentage >= 90 ? gameColors.online : healthPercentage >= 70 ? gameColors.warning : gameColors.error;
124
-
125
- // If no storage keys at all, show minimal UI
126
- if (totalCount === 0) {
127
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
128
- style: styles.mainPanel,
129
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
130
- style: styles.headerBar,
131
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
132
- style: styles.headerLeft,
133
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
134
- style: styles.headerTitle,
135
- children: "STORAGE OVERVIEW"
136
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
137
- style: styles.headerSubtitle,
138
- children: "Persistent app data on device"
139
- })]
140
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
141
- style: styles.statusIndicator,
142
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
143
- style: [styles.statusDot, {
144
- backgroundColor: gameColors.muted
145
- }]
146
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
147
- style: styles.statusText,
148
- children: "EMPTY"
149
- })]
150
- })]
151
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
152
- style: styles.emptyState,
153
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
154
- style: styles.emptyIcon,
155
- children: "\uD83D\uDCE6"
156
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
157
- style: styles.emptyTitle,
158
- children: "NO DATA STORED"
159
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
160
- style: styles.emptySubtitle,
161
- children: "Your app has not saved any data yet"
162
- })]
163
- })]
164
- });
165
- }
166
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
167
- style: styles.mainPanel,
168
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
169
- style: styles.headerBar,
170
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
171
- style: styles.headerLeft,
172
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
173
- style: styles.headerTitle,
174
- children: "STORAGE OVERVIEW"
175
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
176
- style: styles.headerSubtitle,
177
- children: "Persistent app data on device"
178
- })]
179
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
180
- style: [styles.statusIndicator, statusPulseStyle],
181
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
182
- style: [styles.statusDot, {
183
- backgroundColor: healthColor
184
- }]
185
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
186
- style: [styles.statusText, {
187
- color: healthColor
188
- }],
189
- children: healthStatus
190
- })]
191
- })]
192
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
193
- style: styles.healthSection,
194
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
195
- style: styles.healthHeader,
196
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
197
- style: styles.healthLabel,
198
- children: "DATA INTEGRITY"
199
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
200
- style: [styles.healthPercentage, {
201
- color: healthColor
202
- }],
203
- children: [healthPercentage, "%"]
204
- })]
205
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
206
- style: styles.healthBarContainer,
207
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
208
- style: styles.healthBarBg,
209
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
210
- style: [styles.healthBarFill, {
211
- width: `${healthPercentage}%`,
212
- backgroundColor: healthColor,
213
- shadowColor: healthColor
214
- }]
215
- })
216
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
217
- style: styles.healthGridOverlay
218
- })]
219
- })]
220
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
221
- style: styles.statsGrid,
222
- children: storageTypeData.map((item, index) => {
223
- let count = 0;
224
- let isActive = false;
225
- switch (item.key) {
226
- case "valid":
227
- count = presentRequiredCount;
228
- isActive = count > 0;
229
- break;
230
- case "missing":
231
- count = missingCount;
232
- isActive = count > 0;
233
- break;
234
- case "wrongValue":
235
- count = wrongValueCount;
236
- isActive = count > 0;
237
- break;
238
- case "wrongType":
239
- count = wrongTypeCount;
240
- isActive = count > 0;
241
- break;
242
- case "optional":
243
- count = optionalCount;
244
- isActive = count > 0;
245
- break;
246
- }
247
- if (!isActive) return null;
248
- const IconComponent = item.icon;
249
- const isError = item.key === "missing" || item.key === "wrongValue" || item.key === "wrongType";
250
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
251
- style: [styles.statCard, {
252
- borderColor: item.color + "40"
253
- }, isError && styles.statCardError],
254
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
255
- style: [styles.cardGlow, {
256
- backgroundColor: item.color + "10"
257
- }]
258
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
259
- style: styles.cardHeader,
260
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
261
- style: [styles.iconWrapper, {
262
- backgroundColor: item.color + "15"
263
- }],
264
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(IconComponent, {
265
- size: 14,
266
- color: item.color
267
- })
268
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
269
- style: styles.cardInfo,
270
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
271
- style: [styles.cardLabel, {
272
- color: item.color
273
- }],
274
- children: item.label
275
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
276
- style: styles.cardSubtitle,
277
- children: item.subtitle
278
- })]
279
- })]
280
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
281
- style: styles.cardStats,
282
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
283
- style: [styles.statNumber, {
284
- color: item.color
285
- }],
286
- children: count.toString().padStart(2, "0")
287
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
288
- style: [styles.statBar, {
289
- backgroundColor: item.color + "20"
290
- }],
291
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
292
- style: [styles.statBarFill, {
293
- width: `${count / totalCount * 100}%`,
294
- backgroundColor: item.color
295
- }]
296
- })
297
- })]
298
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
299
- style: [styles.cornerIndicator, styles.cornerTL, {
300
- backgroundColor: item.color
301
- }]
302
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
303
- style: [styles.cornerIndicator, styles.cornerBR, {
304
- backgroundColor: item.color
305
- }]
306
- })]
307
- }, item.key);
308
- })
309
- }), (mmkvCount > 0 || asyncCount > 0 || secureCount > 0) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
310
- style: styles.backendSection,
311
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
312
- style: styles.backendTitle,
313
- children: "MEMORY BANKS"
314
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
315
- style: styles.backendGrid,
316
- children: backendTypeData.map(backend => {
317
- let count = 0;
318
- switch (backend.key) {
319
- case "mmkv":
320
- count = mmkvCount;
321
- break;
322
- case "async":
323
- count = asyncCount;
324
- break;
325
- case "secure":
326
- count = secureCount;
327
- break;
328
- }
329
- if (count === 0) return null;
330
- const IconComponent = backend.icon;
331
- const percentage = totalCount > 0 ? Math.round(count / totalCount * 100) : 0;
332
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
333
- style: styles.backendItem,
334
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
335
- style: [styles.backendIcon, {
336
- backgroundColor: backend.color + "15"
337
- }],
338
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(IconComponent, {
339
- size: 12,
340
- color: backend.color
341
- })
342
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
343
- style: styles.backendInfo,
344
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
345
- style: [styles.backendLabel, {
346
- color: backend.color
347
- }],
348
- children: backend.label
349
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
350
- style: styles.backendSubtitle,
351
- children: backend.subtitle
352
- })]
353
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
354
- style: styles.backendStats,
355
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
356
- style: [styles.backendCount, {
357
- color: backend.color
358
- }],
359
- children: count
360
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
361
- style: styles.backendPercent,
362
- children: [percentage, "%"]
363
- })]
364
- })]
365
- }, backend.key);
366
- })
367
- })]
368
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
369
- style: styles.bottomBar,
370
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
371
- style: styles.bottomStats,
372
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
373
- style: styles.bottomStatLabel,
374
- children: "TOTAL KEYS"
375
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
376
- style: styles.bottomStatValue,
377
- children: totalCount
378
- })]
379
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
380
- style: styles.bottomDivider
381
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
382
- style: styles.bottomStats,
383
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
384
- style: styles.bottomStatLabel,
385
- children: "VALID"
386
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
387
- style: [styles.bottomStatValue, {
388
- color: gameColors.online
389
- }],
390
- children: presentRequiredCount + optionalCount
391
- })]
392
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
393
- style: styles.bottomDivider
394
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
395
- style: styles.bottomStats,
396
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
397
- style: styles.bottomStatLabel,
398
- children: "ISSUES"
399
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
400
- style: [styles.bottomStatValue, {
401
- color: gameColors.error
402
- }],
403
- children: missingCount + wrongValueCount + wrongTypeCount
404
- })]
405
- })]
406
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
407
- style: styles.techPattern,
408
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
409
- style: styles.techText,
410
- children: "<DATA>"
411
- })
412
- })]
413
- });
414
- }
415
- const styles = _reactNative.StyleSheet.create({
416
- mainPanel: {
417
- backgroundColor: gameColors.panel,
418
- borderRadius: 16,
419
- padding: 16,
420
- marginBottom: 16,
421
- borderWidth: 1,
422
- borderColor: gameColors.border,
423
- overflow: "hidden",
424
- position: "relative"
425
- },
426
- // Header
427
- headerBar: {
428
- flexDirection: "row",
429
- justifyContent: "space-between",
430
- alignItems: "center",
431
- marginBottom: 20,
432
- paddingBottom: 12,
433
- borderBottomWidth: 1,
434
- borderBottomColor: "rgba(128, 128, 128, 0.2)"
435
- },
436
- headerLeft: {
437
- gap: 2
438
- },
439
- headerTitle: {
440
- fontSize: 14,
441
- fontWeight: "700",
442
- color: gameColors.primary,
443
- fontFamily: "monospace",
444
- letterSpacing: 2
445
- },
446
- headerSubtitle: {
447
- fontSize: 9,
448
- color: gameColors.secondary,
449
- fontFamily: "monospace",
450
- letterSpacing: 1
451
- },
452
- statusIndicator: {
453
- flexDirection: "row",
454
- alignItems: "center",
455
- gap: 6
456
- },
457
- statusDot: {
458
- width: 6,
459
- height: 6,
460
- borderRadius: 3,
461
- shadowOffset: {
462
- width: 0,
463
- height: 0
464
- },
465
- shadowOpacity: 0.8,
466
- shadowRadius: 4
467
- },
468
- statusText: {
469
- fontSize: 10,
470
- fontWeight: "600",
471
- fontFamily: "monospace",
472
- letterSpacing: 1
473
- },
474
- // Health section
475
- healthSection: {
476
- marginBottom: 20
477
- },
478
- healthHeader: {
479
- flexDirection: "row",
480
- justifyContent: "space-between",
481
- alignItems: "center",
482
- marginBottom: 8
483
- },
484
- healthLabel: {
485
- fontSize: 10,
486
- color: gameColors.secondary,
487
- fontFamily: "monospace",
488
- letterSpacing: 1
489
- },
490
- healthPercentage: {
491
- fontSize: 16,
492
- fontWeight: "700",
493
- fontFamily: "monospace",
494
- textShadowOffset: {
495
- width: 0,
496
- height: 0
497
- },
498
- textShadowRadius: 8
499
- },
500
- healthBarContainer: {
501
- position: "relative"
502
- },
503
- healthBarBg: {
504
- height: 6,
505
- backgroundColor: "rgba(128, 128, 128, 0.1)",
506
- borderRadius: 3,
507
- overflow: "hidden"
508
- },
509
- healthBarFill: {
510
- height: "100%",
511
- borderRadius: 3,
512
- shadowOffset: {
513
- width: 0,
514
- height: 0
515
- },
516
- shadowOpacity: 0.6,
517
- shadowRadius: 8
518
- },
519
- healthGridOverlay: {
520
- ..._sharedUi.absoluteFill,
521
- opacity: 0.1,
522
- borderWidth: 1,
523
- borderColor: "rgba(128, 128, 128, 0.2)",
524
- borderRadius: 3
525
- },
526
- // Stats grid
527
- statsGrid: {
528
- gap: 12,
529
- marginBottom: 16
530
- },
531
- statCard: {
532
- backgroundColor: "rgba(0, 0, 0, 0.4)",
533
- borderRadius: 12,
534
- borderWidth: 1,
535
- padding: 12,
536
- position: "relative",
537
- overflow: "hidden"
538
- },
539
- statCardError: {
540
- backgroundColor: "rgba(255, 0, 0, 0.02)"
541
- },
542
- cardGlow: {
543
- ..._sharedUi.absoluteFill,
544
- opacity: 0.3
545
- },
546
- cardHeader: {
547
- flexDirection: "row",
548
- alignItems: "center",
549
- gap: 10,
550
- marginBottom: 10
551
- },
552
- iconWrapper: {
553
- width: 28,
554
- height: 28,
555
- borderRadius: 6,
556
- justifyContent: "center",
557
- alignItems: "center"
558
- },
559
- cardInfo: {
560
- flex: 1
561
- },
562
- cardLabel: {
563
- fontSize: 11,
564
- fontWeight: "700",
565
- fontFamily: "monospace",
566
- letterSpacing: 1,
567
- textShadowOffset: {
568
- width: 0,
569
- height: 0
570
- },
571
- textShadowRadius: 4
572
- },
573
- cardSubtitle: {
574
- fontSize: 9,
575
- color: gameColors.secondary,
576
- fontFamily: "monospace",
577
- marginTop: 1
578
- },
579
- cardStats: {
580
- flexDirection: "row",
581
- alignItems: "center",
582
- gap: 10
583
- },
584
- statNumber: {
585
- fontSize: 24,
586
- fontWeight: "700",
587
- fontFamily: "monospace",
588
- minWidth: 40,
589
- textShadowOffset: {
590
- width: 0,
591
- height: 0
592
- },
593
- textShadowRadius: 10
594
- },
595
- statBar: {
596
- flex: 1,
597
- height: 4,
598
- borderRadius: 2,
599
- overflow: "hidden"
600
- },
601
- statBarFill: {
602
- height: "100%",
603
- borderRadius: 2
604
- },
605
- cornerIndicator: {
606
- position: "absolute",
607
- width: 8,
608
- height: 1,
609
- opacity: 0.6
610
- },
611
- cornerTL: {
612
- top: 0,
613
- left: 0,
614
- width: 1,
615
- height: 8
616
- },
617
- cornerBR: {
618
- bottom: 0,
619
- right: 0,
620
- width: 1,
621
- height: 8
622
- },
623
- // Backend section
624
- backendSection: {
625
- marginBottom: 16
626
- },
627
- backendTitle: {
628
- fontSize: 10,
629
- color: gameColors.secondary,
630
- fontFamily: "monospace",
631
- letterSpacing: 1,
632
- marginBottom: 12
633
- },
634
- backendGrid: {
635
- gap: 8
636
- },
637
- backendItem: {
638
- flexDirection: "row",
639
- alignItems: "center",
640
- backgroundColor: "rgba(128, 128, 128, 0.04)",
641
- borderRadius: 8,
642
- padding: 10,
643
- borderWidth: 1,
644
- borderColor: "rgba(128, 128, 128, 0.1)"
645
- },
646
- backendIcon: {
647
- width: 24,
648
- height: 24,
649
- borderRadius: 4,
650
- justifyContent: "center",
651
- alignItems: "center",
652
- marginRight: 10
653
- },
654
- backendInfo: {
655
- flex: 1
656
- },
657
- backendLabel: {
658
- fontSize: 10,
659
- fontWeight: "600",
660
- fontFamily: "monospace",
661
- letterSpacing: 0.5
662
- },
663
- backendSubtitle: {
664
- fontSize: 8,
665
- color: gameColors.muted,
666
- fontFamily: "monospace"
667
- },
668
- backendStats: {
669
- alignItems: "flex-end"
670
- },
671
- backendCount: {
672
- fontSize: 14,
673
- fontWeight: "700",
674
- fontFamily: "monospace"
675
- },
676
- backendPercent: {
677
- fontSize: 9,
678
- color: gameColors.muted,
679
- fontFamily: "monospace"
680
- },
681
- // Bottom bar
682
- bottomBar: {
683
- flexDirection: "row",
684
- alignItems: "center",
685
- paddingTop: 12,
686
- borderTopWidth: 1,
687
- borderTopColor: "rgba(128, 128, 128, 0.2)"
688
- },
689
- bottomStats: {
690
- flex: 1,
691
- alignItems: "center"
692
- },
693
- bottomStatLabel: {
694
- fontSize: 8,
695
- color: gameColors.muted,
696
- fontFamily: "monospace",
697
- letterSpacing: 1,
698
- marginBottom: 2
699
- },
700
- bottomStatValue: {
701
- fontSize: 14,
702
- fontWeight: "700",
703
- color: gameColors.primary,
704
- fontFamily: "monospace"
705
- },
706
- bottomDivider: {
707
- width: 1,
708
- height: 20,
709
- backgroundColor: "rgba(128, 128, 128, 0.2)"
710
- },
711
- // Empty state
712
- emptyState: {
713
- paddingVertical: 40,
714
- alignItems: "center",
715
- gap: 8
716
- },
717
- emptyIcon: {
718
- fontSize: 32,
719
- color: gameColors.muted,
720
- marginBottom: 8
721
- },
722
- emptyTitle: {
723
- fontSize: 12,
724
- color: gameColors.secondary,
725
- fontFamily: "monospace",
726
- letterSpacing: 2
727
- },
728
- emptySubtitle: {
729
- fontSize: 10,
730
- color: gameColors.muted,
731
- fontFamily: "monospace"
732
- },
733
- // Tech decoration
734
- techPattern: {
735
- position: "absolute",
736
- top: 16,
737
- right: 16,
738
- opacity: 0.03
739
- },
740
- techText: {
741
- fontSize: 8,
742
- fontFamily: "monospace",
743
- color: gameColors.info,
744
- letterSpacing: 1
745
- }
746
- });