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