@wakastellar/ui 2.1.2 → 2.3.2

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 (123) hide show
  1. package/dist/blocks/apm-overview/index.d.ts +58 -0
  2. package/dist/blocks/cicd-builder/index.d.ts +47 -0
  3. package/dist/blocks/cloud-cost-dashboard/index.d.ts +49 -0
  4. package/dist/blocks/container-orchestrator/index.d.ts +63 -0
  5. package/dist/blocks/database-admin/index.d.ts +84 -0
  6. package/dist/blocks/gitops-sync-status/index.d.ts +45 -0
  7. package/dist/blocks/incident-manager/index.d.ts +44 -0
  8. package/dist/blocks/index.d.ts +10 -0
  9. package/dist/blocks/infrastructure-map/index.d.ts +32 -0
  10. package/dist/blocks/on-call-schedule/index.d.ts +43 -0
  11. package/dist/blocks/release-notes/index.d.ts +49 -0
  12. package/dist/components/index.d.ts +34 -0
  13. package/dist/components/waka-ad-banner/index.d.ts +36 -0
  14. package/dist/components/waka-ad-fallback/index.d.ts +33 -0
  15. package/dist/components/waka-ad-inline/index.d.ts +15 -0
  16. package/dist/components/waka-ad-interstitial/index.d.ts +26 -0
  17. package/dist/components/waka-ad-placeholder/index.d.ts +17 -0
  18. package/dist/components/waka-ad-provider/index.d.ts +103 -0
  19. package/dist/components/waka-ad-sidebar/index.d.ts +18 -0
  20. package/dist/components/waka-ad-sticky-footer/index.d.ts +17 -0
  21. package/dist/components/waka-alert-panel/index.d.ts +45 -0
  22. package/dist/components/waka-artifact-list/index.d.ts +32 -0
  23. package/dist/components/waka-build-matrix/index.d.ts +36 -0
  24. package/dist/components/waka-config-comparator/index.d.ts +37 -0
  25. package/dist/components/waka-container-list/index.d.ts +51 -0
  26. package/dist/components/waka-content-recommendation/index.d.ts +23 -0
  27. package/dist/components/waka-database-card/index.d.ts +46 -0
  28. package/dist/components/waka-dependency-tree/index.d.ts +38 -0
  29. package/dist/components/waka-env-var-editor/index.d.ts +30 -0
  30. package/dist/components/waka-feature-flag-row/index.d.ts +45 -0
  31. package/dist/components/waka-kubernetes-overview/index.d.ts +98 -0
  32. package/dist/components/waka-log-viewer/index.d.ts +38 -0
  33. package/dist/components/waka-migration-list/index.d.ts +36 -0
  34. package/dist/components/waka-outstream-video/index.d.ts +24 -0
  35. package/dist/components/waka-pod-card/index.d.ts +73 -0
  36. package/dist/components/waka-query-explain/index.d.ts +48 -0
  37. package/dist/components/waka-secret-card/index.d.ts +43 -0
  38. package/dist/components/waka-security-scan-result/index.d.ts +45 -0
  39. package/dist/components/waka-service-graph/index.d.ts +44 -0
  40. package/dist/components/waka-sponsored-badge/index.d.ts +20 -0
  41. package/dist/components/waka-sponsored-card/index.d.ts +25 -0
  42. package/dist/components/waka-sponsored-feed/index.d.ts +31 -0
  43. package/dist/components/waka-test-report/index.d.ts +60 -0
  44. package/dist/components/waka-trace-viewer/index.d.ts +36 -0
  45. package/dist/components/waka-video-ad/index.d.ts +32 -0
  46. package/dist/components/waka-video-overlay/index.d.ts +26 -0
  47. package/dist/index.cjs.js +251 -200
  48. package/dist/index.d.ts +1 -0
  49. package/dist/index.es.js +47315 -35823
  50. package/dist/utils/security.d.ts +96 -0
  51. package/package.json +4 -4
  52. package/src/blocks/apm-overview/index.tsx +672 -0
  53. package/src/blocks/cicd-builder/index.tsx +738 -0
  54. package/src/blocks/cloud-cost-dashboard/index.tsx +597 -0
  55. package/src/blocks/container-orchestrator/index.tsx +729 -0
  56. package/src/blocks/database-admin/index.tsx +679 -0
  57. package/src/blocks/gitops-sync-status/index.tsx +557 -0
  58. package/src/blocks/incident-manager/index.tsx +586 -0
  59. package/src/blocks/index.ts +119 -0
  60. package/src/blocks/infrastructure-map/index.tsx +638 -0
  61. package/src/blocks/on-call-schedule/index.tsx +615 -0
  62. package/src/blocks/release-notes/index.tsx +643 -0
  63. package/src/blocks/sidebar/index.tsx +6 -6
  64. package/src/components/DataTable/templates/index.tsx +3 -2
  65. package/src/components/index.ts +283 -0
  66. package/src/components/waka-3d-pie-chart/index.tsx +11 -11
  67. package/src/components/waka-achievement-unlock/index.tsx +16 -16
  68. package/src/components/waka-ad-banner/index.tsx +275 -0
  69. package/src/components/waka-ad-fallback/index.tsx +181 -0
  70. package/src/components/waka-ad-inline/index.tsx +103 -0
  71. package/src/components/waka-ad-interstitial/index.tsx +278 -0
  72. package/src/components/waka-ad-placeholder/index.tsx +84 -0
  73. package/src/components/waka-ad-provider/index.tsx +329 -0
  74. package/src/components/waka-ad-sidebar/index.tsx +113 -0
  75. package/src/components/waka-ad-sticky-footer/index.tsx +125 -0
  76. package/src/components/waka-alert-panel/index.tsx +493 -0
  77. package/src/components/waka-artifact-list/index.tsx +416 -0
  78. package/src/components/waka-badge-showcase/index.tsx +12 -11
  79. package/src/components/waka-build-matrix/index.tsx +396 -0
  80. package/src/components/waka-command-bar/index.tsx +2 -1
  81. package/src/components/waka-config-comparator/index.tsx +416 -0
  82. package/src/components/waka-container-list/index.tsx +475 -0
  83. package/src/components/waka-content-recommendation/index.tsx +294 -0
  84. package/src/components/waka-cost-breakdown/index.tsx +10 -10
  85. package/src/components/waka-database-card/index.tsx +473 -0
  86. package/src/components/waka-dependency-tree/index.tsx +542 -0
  87. package/src/components/waka-env-var-editor/index.tsx +417 -0
  88. package/src/components/waka-feature-flag-row/index.tsx +386 -0
  89. package/src/components/waka-funnel-chart/index.tsx +8 -8
  90. package/src/components/waka-health-pulse/index.tsx +6 -6
  91. package/src/components/waka-kubernetes-overview/index.tsx +536 -0
  92. package/src/components/waka-leaderboard/index.tsx +9 -9
  93. package/src/components/waka-log-viewer/index.tsx +386 -0
  94. package/src/components/waka-loot-box/index.tsx +20 -20
  95. package/src/components/waka-migration-list/index.tsx +487 -0
  96. package/src/components/waka-outstream-video/index.tsx +240 -0
  97. package/src/components/waka-player-card/index.tsx +5 -5
  98. package/src/components/waka-pod-card/index.tsx +528 -0
  99. package/src/components/waka-query-explain/index.tsx +657 -0
  100. package/src/components/waka-quota-bar/index.tsx +4 -4
  101. package/src/components/waka-radar-score/index.tsx +10 -10
  102. package/src/components/waka-scratch-card/index.tsx +5 -4
  103. package/src/components/waka-secret-card/index.tsx +371 -0
  104. package/src/components/waka-security-scan-result/index.tsx +473 -0
  105. package/src/components/waka-server-rack/index.tsx +28 -27
  106. package/src/components/waka-service-graph/index.tsx +445 -0
  107. package/src/components/waka-sponsored-badge/index.tsx +97 -0
  108. package/src/components/waka-sponsored-card/index.tsx +275 -0
  109. package/src/components/waka-sponsored-feed/index.tsx +127 -0
  110. package/src/components/waka-spotlight/index.tsx +2 -1
  111. package/src/components/waka-success-explosion/index.tsx +4 -4
  112. package/src/components/waka-test-report/index.tsx +469 -0
  113. package/src/components/waka-trace-viewer/index.tsx +490 -0
  114. package/src/components/waka-video-ad/index.tsx +406 -0
  115. package/src/components/waka-video-overlay/index.tsx +257 -0
  116. package/src/components/waka-xp-bar/index.tsx +13 -13
  117. package/src/styles/base.css +16 -0
  118. package/src/styles/tailwind.preset.js +12 -0
  119. package/src/styles/themes/forest.css +16 -0
  120. package/src/styles/themes/monochrome.css +16 -0
  121. package/src/styles/themes/perpetuity.css +16 -0
  122. package/src/styles/themes/sunset.css +16 -0
  123. package/src/styles/themes/twilight.css +16 -0
@@ -0,0 +1,386 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "../../utils/cn"
5
+ import { Button } from "../button"
6
+ import { Input } from "../input"
7
+ import { Badge } from "../badge"
8
+ import { ScrollArea } from "../scroll-area"
9
+ import {
10
+ Select,
11
+ SelectContent,
12
+ SelectItem,
13
+ SelectTrigger,
14
+ SelectValue,
15
+ } from "../select"
16
+ import {
17
+ Search,
18
+ Filter,
19
+ Download,
20
+ Pause,
21
+ Play,
22
+ Trash2,
23
+ ChevronDown,
24
+ ChevronRight,
25
+ AlertCircle,
26
+ AlertTriangle,
27
+ Info,
28
+ Bug,
29
+ Clock,
30
+ RefreshCw,
31
+ } from "lucide-react"
32
+
33
+ export type LogLevel = "error" | "warn" | "info" | "debug" | "trace"
34
+
35
+ export interface LogEntry {
36
+ id: string
37
+ timestamp: Date
38
+ level: LogLevel
39
+ message: string
40
+ source?: string
41
+ metadata?: Record<string, unknown>
42
+ stackTrace?: string
43
+ }
44
+
45
+ export interface WakaLogViewerProps {
46
+ /** Log entries to display */
47
+ logs: LogEntry[]
48
+ /** Callback when requesting more logs */
49
+ onLoadMore?: () => void
50
+ /** Callback when clearing logs */
51
+ onClear?: () => void
52
+ /** Callback when exporting logs */
53
+ onExport?: (logs: LogEntry[]) => void
54
+ /** Whether streaming is active */
55
+ isStreaming?: boolean
56
+ /** Callback to toggle streaming */
57
+ onToggleStreaming?: () => void
58
+ /** Maximum number of logs to display */
59
+ maxLogs?: number
60
+ /** Show timestamp */
61
+ showTimestamp?: boolean
62
+ /** Show source */
63
+ showSource?: boolean
64
+ /** Enable auto-scroll to bottom */
65
+ autoScroll?: boolean
66
+ /** Custom class name */
67
+ className?: string
68
+ /** Title */
69
+ title?: string
70
+ }
71
+
72
+ const levelConfig: Record<LogLevel, { icon: React.ElementType; color: string; bgColor: string }> = {
73
+ error: { icon: AlertCircle, color: "text-red-500", bgColor: "bg-red-500/10" },
74
+ warn: { icon: AlertTriangle, color: "text-yellow-500", bgColor: "bg-yellow-500/10" },
75
+ info: { icon: Info, color: "text-blue-500", bgColor: "bg-blue-500/10" },
76
+ debug: { icon: Bug, color: "text-purple-500", bgColor: "bg-purple-500/10" },
77
+ trace: { icon: Clock, color: "text-gray-500", bgColor: "bg-gray-500/10" },
78
+ }
79
+
80
+ function LogEntryRow({
81
+ entry,
82
+ showTimestamp,
83
+ showSource,
84
+ isExpanded,
85
+ onToggleExpand,
86
+ }: {
87
+ entry: LogEntry
88
+ showTimestamp: boolean
89
+ showSource: boolean
90
+ isExpanded: boolean
91
+ onToggleExpand: () => void
92
+ }) {
93
+ const config = levelConfig[entry.level]
94
+ const Icon = config.icon
95
+ const hasDetails = entry.metadata || entry.stackTrace
96
+
97
+ return (
98
+ <div className={cn("border-b border-border/50 hover:bg-muted/30 transition-colors", config.bgColor)}>
99
+ <div
100
+ className={cn(
101
+ "flex items-start gap-2 px-3 py-2 font-mono text-sm",
102
+ hasDetails && "cursor-pointer"
103
+ )}
104
+ onClick={hasDetails ? onToggleExpand : undefined}
105
+ >
106
+ {hasDetails && (
107
+ <button className="mt-0.5 text-muted-foreground hover:text-foreground">
108
+ {isExpanded ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
109
+ </button>
110
+ )}
111
+
112
+ <Icon className={cn("h-4 w-4 mt-0.5 shrink-0", config.color)} />
113
+
114
+ {showTimestamp && (
115
+ <span className="text-muted-foreground shrink-0 text-xs">
116
+ {entry.timestamp.toLocaleTimeString("fr-FR", {
117
+ hour: "2-digit",
118
+ minute: "2-digit",
119
+ second: "2-digit",
120
+ })}.{entry.timestamp.getMilliseconds().toString().padStart(3, '0')}
121
+ </span>
122
+ )}
123
+
124
+ <Badge variant="outline" className={cn("shrink-0 uppercase text-xs", config.color)}>
125
+ {entry.level}
126
+ </Badge>
127
+
128
+ {showSource && entry.source && (
129
+ <span className="text-muted-foreground shrink-0">[{entry.source}]</span>
130
+ )}
131
+
132
+ <span className="flex-1 break-all whitespace-pre-wrap">{entry.message}</span>
133
+ </div>
134
+
135
+ {isExpanded && hasDetails && (
136
+ <div className="px-3 pb-3 pl-10 space-y-2">
137
+ {entry.metadata && (
138
+ <div className="bg-muted/50 rounded p-2 font-mono text-xs">
139
+ <pre className="overflow-x-auto">
140
+ {JSON.stringify(entry.metadata, null, 2)}
141
+ </pre>
142
+ </div>
143
+ )}
144
+ {entry.stackTrace && (
145
+ <div className="bg-red-500/5 border border-red-500/20 rounded p-2 font-mono text-xs text-red-400">
146
+ <pre className="overflow-x-auto whitespace-pre-wrap">{entry.stackTrace}</pre>
147
+ </div>
148
+ )}
149
+ </div>
150
+ )}
151
+ </div>
152
+ )
153
+ }
154
+
155
+ export function WakaLogViewer({
156
+ logs,
157
+ onLoadMore,
158
+ onClear,
159
+ onExport,
160
+ isStreaming = false,
161
+ onToggleStreaming,
162
+ maxLogs = 1000,
163
+ showTimestamp = true,
164
+ showSource = true,
165
+ autoScroll = true,
166
+ className,
167
+ title = "Logs",
168
+ }: WakaLogViewerProps) {
169
+ const [searchQuery, setSearchQuery] = React.useState("")
170
+ const [levelFilter, setLevelFilter] = React.useState<LogLevel | "all">("all")
171
+ const [expandedIds, setExpandedIds] = React.useState<Set<string>>(new Set())
172
+ const scrollRef = React.useRef<HTMLDivElement>(null)
173
+
174
+ // Filter logs
175
+ const filteredLogs = React.useMemo(() => {
176
+ return logs
177
+ .filter(log => {
178
+ if (levelFilter !== "all" && log.level !== levelFilter) return false
179
+ if (searchQuery) {
180
+ const query = searchQuery.toLowerCase()
181
+ return (
182
+ log.message.toLowerCase().includes(query) ||
183
+ log.source?.toLowerCase().includes(query) ||
184
+ JSON.stringify(log.metadata).toLowerCase().includes(query)
185
+ )
186
+ }
187
+ return true
188
+ })
189
+ .slice(-maxLogs)
190
+ }, [logs, levelFilter, searchQuery, maxLogs])
191
+
192
+ // Auto-scroll to bottom
193
+ React.useEffect(() => {
194
+ if (autoScroll && scrollRef.current) {
195
+ scrollRef.current.scrollTop = scrollRef.current.scrollHeight
196
+ }
197
+ }, [filteredLogs, autoScroll])
198
+
199
+ const toggleExpand = (id: string) => {
200
+ setExpandedIds(prev => {
201
+ const next = new Set(prev)
202
+ if (next.has(id)) {
203
+ next.delete(id)
204
+ } else {
205
+ next.add(id)
206
+ }
207
+ return next
208
+ })
209
+ }
210
+
211
+ // Count by level
212
+ const levelCounts = React.useMemo(() => {
213
+ return logs.reduce((acc, log) => {
214
+ acc[log.level] = (acc[log.level] || 0) + 1
215
+ return acc
216
+ }, {} as Record<LogLevel, number>)
217
+ }, [logs])
218
+
219
+ return (
220
+ <div className={cn("flex flex-col h-full border rounded-lg bg-background", className)}>
221
+ {/* Header */}
222
+ <div className="flex items-center justify-between gap-4 p-3 border-b">
223
+ <div className="flex items-center gap-2">
224
+ <h3 className="font-semibold">{title}</h3>
225
+ <Badge variant="secondary">{filteredLogs.length}</Badge>
226
+ {isStreaming && (
227
+ <Badge variant="default" className="bg-green-500 animate-pulse">
228
+ Live
229
+ </Badge>
230
+ )}
231
+ </div>
232
+
233
+ <div className="flex items-center gap-2">
234
+ {/* Level counts */}
235
+ <div className="hidden md:flex items-center gap-1">
236
+ {(["error", "warn", "info", "debug"] as LogLevel[]).map(level => {
237
+ const config = levelConfig[level]
238
+ const count = levelCounts[level] || 0
239
+ return (
240
+ <Badge
241
+ key={level}
242
+ variant="outline"
243
+ className={cn("text-xs cursor-pointer", config.color)}
244
+ onClick={() => setLevelFilter(levelFilter === level ? "all" : level)}
245
+ >
246
+ {level}: {count}
247
+ </Badge>
248
+ )
249
+ })}
250
+ </div>
251
+ </div>
252
+ </div>
253
+
254
+ {/* Toolbar */}
255
+ <div className="flex items-center gap-2 p-2 border-b bg-muted/30">
256
+ <div className="relative flex-1 max-w-sm">
257
+ <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
258
+ <Input
259
+ placeholder="Rechercher..."
260
+ value={searchQuery}
261
+ onChange={(e) => setSearchQuery(e.target.value)}
262
+ className="pl-8 h-8"
263
+ />
264
+ </div>
265
+
266
+ <Select value={levelFilter} onValueChange={(v) => setLevelFilter(v as LogLevel | "all")}>
267
+ <SelectTrigger className="w-[120px] h-8">
268
+ <Filter className="h-4 w-4 mr-2" />
269
+ <SelectValue placeholder="Niveau" />
270
+ </SelectTrigger>
271
+ <SelectContent>
272
+ <SelectItem value="all">Tous</SelectItem>
273
+ <SelectItem value="error">Error</SelectItem>
274
+ <SelectItem value="warn">Warn</SelectItem>
275
+ <SelectItem value="info">Info</SelectItem>
276
+ <SelectItem value="debug">Debug</SelectItem>
277
+ <SelectItem value="trace">Trace</SelectItem>
278
+ </SelectContent>
279
+ </Select>
280
+
281
+ <div className="flex items-center gap-1">
282
+ {onToggleStreaming && (
283
+ <Button
284
+ variant="ghost"
285
+ size="sm"
286
+ onClick={onToggleStreaming}
287
+ className="h-8"
288
+ >
289
+ {isStreaming ? <Pause className="h-4 w-4" /> : <Play className="h-4 w-4" />}
290
+ </Button>
291
+ )}
292
+
293
+ {onLoadMore && (
294
+ <Button variant="ghost" size="sm" onClick={onLoadMore} className="h-8">
295
+ <RefreshCw className="h-4 w-4" />
296
+ </Button>
297
+ )}
298
+
299
+ {onExport && (
300
+ <Button
301
+ variant="ghost"
302
+ size="sm"
303
+ onClick={() => onExport(filteredLogs)}
304
+ className="h-8"
305
+ >
306
+ <Download className="h-4 w-4" />
307
+ </Button>
308
+ )}
309
+
310
+ {onClear && (
311
+ <Button variant="ghost" size="sm" onClick={onClear} className="h-8 text-destructive">
312
+ <Trash2 className="h-4 w-4" />
313
+ </Button>
314
+ )}
315
+ </div>
316
+ </div>
317
+
318
+ {/* Log entries */}
319
+ <ScrollArea ref={scrollRef} className="flex-1">
320
+ <div className="min-w-max">
321
+ {filteredLogs.length === 0 ? (
322
+ <div className="flex items-center justify-center h-32 text-muted-foreground">
323
+ Aucun log à afficher
324
+ </div>
325
+ ) : (
326
+ filteredLogs.map(entry => (
327
+ <LogEntryRow
328
+ key={entry.id}
329
+ entry={entry}
330
+ showTimestamp={showTimestamp}
331
+ showSource={showSource}
332
+ isExpanded={expandedIds.has(entry.id)}
333
+ onToggleExpand={() => toggleExpand(entry.id)}
334
+ />
335
+ ))
336
+ )}
337
+ </div>
338
+ </ScrollArea>
339
+ </div>
340
+ )
341
+ }
342
+
343
+ // Default sample logs for demo
344
+ export const defaultLogs: LogEntry[] = [
345
+ {
346
+ id: "1",
347
+ timestamp: new Date(),
348
+ level: "info",
349
+ message: "Application started successfully",
350
+ source: "main",
351
+ },
352
+ {
353
+ id: "2",
354
+ timestamp: new Date(),
355
+ level: "debug",
356
+ message: "Loading configuration from /etc/app/config.yaml",
357
+ source: "config",
358
+ metadata: { path: "/etc/app/config.yaml", format: "yaml" },
359
+ },
360
+ {
361
+ id: "3",
362
+ timestamp: new Date(),
363
+ level: "warn",
364
+ message: "Deprecated API version detected, please upgrade to v2",
365
+ source: "api",
366
+ },
367
+ {
368
+ id: "4",
369
+ timestamp: new Date(),
370
+ level: "error",
371
+ message: "Failed to connect to database",
372
+ source: "db",
373
+ metadata: { host: "localhost", port: 5432 },
374
+ stackTrace: `Error: Connection refused
375
+ at PostgresClient.connect (/app/node_modules/pg/lib/client.js:123:15)
376
+ at async DatabaseService.init (/app/src/services/database.ts:45:5)
377
+ at async bootstrap (/app/src/main.ts:12:3)`,
378
+ },
379
+ {
380
+ id: "5",
381
+ timestamp: new Date(),
382
+ level: "info",
383
+ message: "Retry connection attempt 1/3",
384
+ source: "db",
385
+ },
386
+ ]
@@ -102,46 +102,46 @@ const rarityConfig = {
102
102
  common: {
103
103
  gradient: "from-slate-400 to-slate-600",
104
104
  glow: "shadow-slate-400/50",
105
- glowColor: "#94a3b8",
105
+ glowColor: "hsl(var(--muted-foreground))",
106
106
  borderColor: "border-slate-400",
107
- bgColor: "bg-slate-100",
108
- textColor: "text-slate-600",
109
- particleColors: ["#94a3b8", "#cbd5e1", "#64748b"],
107
+ bgColor: "bg-slate-100 dark:bg-slate-900",
108
+ textColor: "text-slate-600 dark:text-slate-400",
109
+ particleColors: ["hsl(var(--muted-foreground))", "hsl(var(--muted))", "hsl(var(--border))"],
110
110
  label: "Common",
111
- beamColor: "rgba(148, 163, 184, 0.8)",
111
+ beamColor: "hsl(var(--muted-foreground) / 0.8)",
112
112
  },
113
113
  rare: {
114
114
  gradient: "from-blue-400 to-blue-600",
115
115
  glow: "shadow-blue-400/50",
116
- glowColor: "#60a5fa",
116
+ glowColor: "hsl(var(--info))",
117
117
  borderColor: "border-blue-400",
118
- bgColor: "bg-blue-100",
119
- textColor: "text-blue-600",
120
- particleColors: ["#60a5fa", "#93c5fd", "#3b82f6"],
118
+ bgColor: "bg-blue-100 dark:bg-blue-950",
119
+ textColor: "text-blue-600 dark:text-blue-400",
120
+ particleColors: ["hsl(var(--info))", "hsl(var(--chart-1))", "hsl(var(--primary))"],
121
121
  label: "Rare",
122
- beamColor: "rgba(96, 165, 250, 0.8)",
122
+ beamColor: "hsl(var(--info) / 0.8)",
123
123
  },
124
124
  epic: {
125
125
  gradient: "from-purple-400 to-purple-600",
126
126
  glow: "shadow-purple-400/50",
127
- glowColor: "#a855f7",
127
+ glowColor: "hsl(var(--chart-2))",
128
128
  borderColor: "border-purple-400",
129
- bgColor: "bg-purple-100",
130
- textColor: "text-purple-600",
131
- particleColors: ["#a855f7", "#c084fc", "#9333ea"],
129
+ bgColor: "bg-purple-100 dark:bg-purple-950",
130
+ textColor: "text-purple-600 dark:text-purple-400",
131
+ particleColors: ["hsl(var(--chart-2))", "hsl(var(--chart-3))", "hsl(var(--primary))"],
132
132
  label: "Epic",
133
- beamColor: "rgba(168, 85, 247, 0.8)",
133
+ beamColor: "hsl(var(--chart-2) / 0.8)",
134
134
  },
135
135
  legendary: {
136
136
  gradient: "from-amber-400 via-orange-500 to-red-500",
137
137
  glow: "shadow-amber-400/50",
138
- glowColor: "#fbbf24",
138
+ glowColor: "hsl(var(--warning))",
139
139
  borderColor: "border-amber-400",
140
- bgColor: "bg-amber-100",
141
- textColor: "text-amber-600",
142
- particleColors: ["#fbbf24", "#f59e0b", "#ef4444", "#fcd34d"],
140
+ bgColor: "bg-amber-100 dark:bg-amber-950",
141
+ textColor: "text-amber-600 dark:text-amber-400",
142
+ particleColors: ["hsl(var(--warning))", "hsl(var(--chart-4))", "hsl(var(--destructive))", "hsl(var(--chart-5))"],
143
143
  label: "Legendary",
144
- beamColor: "rgba(251, 191, 36, 0.9)",
144
+ beamColor: "hsl(var(--warning) / 0.9)",
145
145
  },
146
146
  }
147
147