blumenjs 0.1.5 → 0.1.7

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.
@@ -1,544 +1,395 @@
1
1
  import React, { useState } from "react";
2
2
 
3
3
  const DashboardPage: React.FC = () => {
4
- const [activeNav, setActiveNav] = useState("overview");
5
-
4
+ const [activeNav, setActiveNav] = useState("dashboard");
5
+ const nav = [
6
+ { id: "dashboard", label: "Dashboard" }, { id: "payments", label: "Payments" },
7
+ { id: "transactions", label: "Transactions" }, { id: "invoices", label: "Invoices" },
8
+ { id: "cards", label: "Cards" }, { id: "savings", label: "Saving Plans" },
9
+ { id: "investments", label: "Investments" }, { id: "inbox", label: "Inbox" },
10
+ ];
6
11
  const stats = [
7
- { label: "Total Users", value: "12,847", change: "+12.5%", up: true, icon: "◎" },
8
- { label: "Revenue", value: "$48,290", change: "+8.2%", up: true, icon: "◆" },
9
- { label: "Active Now", value: "1,429", change: "+3.1%", up: true, icon: "●" },
10
- { label: "Bounce Rate", value: "24.3%", change: "-2.4%", up: false, icon: "◇" },
12
+ { label: "Total Income", value: "$78,000", change: "+17.5%", up: true },
13
+ { label: "Total Expense", value: "$43,000", change: "-12.4%", up: false },
14
+ { label: "Total Savings", value: "$56,000", change: "+24.5%", up: true },
11
15
  ];
12
-
13
- const navItems = [
14
- { id: "overview", label: "Overview", icon: "" },
15
- { id: "analytics", label: "Analytics", icon: "" },
16
- { id: "users", label: "Users", icon: "" },
17
- { id: "settings", label: "Settings", icon: "⬡" },
16
+ const bars = [
17
+ { m: "Jan", i: 50, e: 35 }, { m: "Feb", i: 55, e: 40 }, { m: "Mar", i: 48, e: 45 },
18
+ { m: "Apr", i: 62, e: 38 }, { m: "May", i: 58, e: 48 }, { m: "Jun", i: 72, e: 42 },
19
+ { m: "Jul", i: 60, e: 38 }, { m: "Aug", i: 68, e: 52 }, { m: "Sep", i: 75, e: 50 },
20
+ { m: "Oct", i: 82, e: 58 }, { m: "Nov", i: 70, e: 45 }, { m: "Dec", i: 78, e: 52 },
18
21
  ];
19
-
20
- const recentActivity = [
21
- { user: "Sarah Chen", action: "Updated billing info", time: "2 min ago", avatar: "SC" },
22
- { user: "Alex Rivera", action: "Created new project", time: "15 min ago", avatar: "AR" },
23
- { user: "Jamie Park", action: "Deployed to production", time: "1 hr ago", avatar: "JP" },
24
- { user: "Morgan Ellis", action: "Invited team member", time: "3 hrs ago", avatar: "ME" },
25
- { user: "Taylor Kim", action: "Upgraded to Pro plan", time: "5 hrs ago", avatar: "TK" },
22
+ const txns = [
23
+ { name: "Electricity Bill", cat: "Payments", date: "2028-03-01", amt: "$295.81", note: "Monthly electricity bill", status: "Failed" },
24
+ { name: "Weekly Groceries", cat: "Shopping", date: "2028-03-04", amt: "$204.07", note: "Local supermarket", status: "Completed" },
25
+ { name: "Movie Night", cat: "Entertainment", date: "2028-02-27", amt: "$97.84", note: "Tickets and snacks", status: "Pending" },
26
+ { name: "Medical Check-up", cat: "Healthcare", date: "2028-02-07", amt: "$323.33", note: "Routine health check", status: "Pending" },
27
+ ];
28
+ const funds = [
29
+ { name: "Emergency Fund", saved: "$5,000", pct: 50, target: "$10,000" },
30
+ { name: "Vacation Fund", saved: "$3,000", pct: 60, target: "$5,000" },
31
+ { name: "Home Down Payment", saved: "$7,250", pct: 36, target: "$20,000" },
32
+ ];
33
+ const expenses = [
34
+ { label: "Rent & Living", pct: "60%", amt: "$2,100", c: "#16a34a" },
35
+ { label: "Investment", pct: "15%", amt: "$525", c: "#22c55e" },
36
+ { label: "Education", pct: "12%", amt: "$420", c: "#4ade80" },
37
+ { label: "Food & Drink", pct: "8%", amt: "$280", c: "#86efac" },
38
+ { label: "Entertainment", pct: "5%", amt: "$175", c: "#bbf7d0" },
26
39
  ];
40
+ const acts = [
41
+ { u: "Jamie Smith", a: "updated account settings", t: "16:05", c: "#22c55e" },
42
+ { u: "Alex Johnson", a: "logged in", t: "13:05", c: "#3b82f6" },
43
+ { u: "Morgan Lee", a: "added a new savings goal", t: "02:05", c: "#f59e0b" },
44
+ ];
45
+ const actsY = [
46
+ { u: "Taylor Green", a: "reviewed recent transactions", t: "21:05", c: "#8b5cf6" },
47
+ { u: "Wilson Baptista", a: "transferred funds", t: "09:06", c: "#ef4444" },
48
+ ];
49
+ const sc: Record<string, { bg: string; fg: string }> = {
50
+ Failed: { bg: "#fef2f2", fg: "#dc2626" },
51
+ Completed: { bg: "#f0fdf4", fg: "#16a34a" },
52
+ Pending: { bg: "#fffbeb", fg: "#d97706" },
53
+ };
27
54
 
28
55
  return (
29
- <div className="bl-dash">
30
- <style
31
- dangerouslySetInnerHTML={{
32
- __html: `
33
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
34
-
35
- @keyframes fade-up {
36
- from { opacity: 0; transform: translateY(16px); }
37
- to { opacity: 1; transform: translateY(0); }
38
- }
39
-
40
- @keyframes shimmer {
41
- 0% { background-position: -200% 0; }
42
- 100% { background-position: 200% 0; }
43
- }
44
-
45
- @keyframes pulse-ring {
46
- 0% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.3); }
47
- 70% { box-shadow: 0 0 0 8px rgba(99, 102, 241, 0); }
48
- 100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0); }
49
- }
50
-
51
- .bl-dash * { box-sizing: border-box; margin: 0; padding: 0; }
52
-
53
- .bl-dash {
54
- min-height: 100vh;
55
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
56
- background: #09090b;
57
- color: #fafafa;
58
- display: flex;
59
- }
60
-
61
- /* ── Sidebar ── */
62
- .bl-sidebar {
63
- width: 260px;
64
- background: #0f0f12;
65
- border-right: 1px solid rgba(255,255,255,0.06);
66
- padding: 24px 16px;
67
- display: flex;
68
- flex-direction: column;
69
- position: fixed;
70
- top: 0;
71
- bottom: 0;
72
- left: 0;
73
- z-index: 10;
74
- }
75
-
76
- .bl-sidebar-brand {
77
- display: flex;
78
- align-items: center;
79
- gap: 12px;
80
- padding: 8px 12px;
81
- margin-bottom: 32px;
82
- }
83
-
84
- .bl-sidebar-logo {
85
- width: 36px; height: 36px;
86
- border-radius: 10px;
87
- background: linear-gradient(135deg, #6366f1, #8b5cf6);
88
- display: flex;
89
- align-items: center;
90
- justify-content: center;
91
- font-size: 1.1rem;
92
- }
93
-
94
- .bl-sidebar-name {
95
- font-size: 1.1rem;
96
- font-weight: 700;
97
- letter-spacing: -0.02em;
98
- }
99
-
100
- .bl-sidebar-name span {
101
- color: #6b7280;
102
- font-weight: 400;
103
- font-size: 0.75rem;
104
- display: block;
105
- margin-top: 2px;
106
- }
107
-
108
- .bl-nav { list-style: none; flex: 1; }
109
-
110
- .bl-nav-item {
111
- display: flex;
112
- align-items: center;
113
- gap: 12px;
114
- padding: 10px 14px;
115
- border-radius: 10px;
116
- font-size: 0.88rem;
117
- font-weight: 500;
118
- color: #6b7280;
119
- cursor: pointer;
120
- transition: all 0.2s;
121
- margin-bottom: 4px;
122
- border: none;
123
- background: none;
124
- width: 100%;
125
- font-family: inherit;
126
- text-align: left;
127
- }
128
-
129
- .bl-nav-item:hover {
130
- color: #d1d5db;
131
- background: rgba(255,255,255,0.04);
132
- }
133
-
134
- .bl-nav-item.active {
135
- color: #fff;
136
- background: rgba(99, 102, 241, 0.12);
137
- }
138
-
139
- .bl-nav-icon {
140
- width: 20px;
141
- text-align: center;
142
- font-size: 0.9rem;
143
- }
144
-
145
- .bl-sidebar-footer {
146
- padding: 16px 14px;
147
- border-top: 1px solid rgba(255,255,255,0.06);
148
- display: flex;
149
- align-items: center;
150
- gap: 12px;
151
- }
152
-
153
- .bl-avatar {
154
- width: 34px; height: 34px;
155
- border-radius: 8px;
156
- background: linear-gradient(135deg, #1e1b4b, #312e81);
157
- display: flex;
158
- align-items: center;
159
- justify-content: center;
160
- font-size: 0.7rem;
161
- font-weight: 600;
162
- color: #a5b4fc;
163
- }
164
-
165
- .bl-user-name {
166
- font-size: 0.82rem;
167
- font-weight: 600;
168
- color: #e5e7eb;
169
- }
170
-
171
- .bl-user-role {
172
- font-size: 0.72rem;
173
- color: #6b7280;
174
- }
175
-
176
- /* ── Main ── */
177
- .bl-main {
178
- flex: 1;
179
- margin-left: 260px;
180
- padding: 32px 40px;
181
- }
182
-
183
- .bl-header {
184
- display: flex;
185
- justify-content: space-between;
186
- align-items: center;
187
- margin-bottom: 36px;
188
- animation: fade-up 0.6s ease-out both;
189
- }
190
-
191
- .bl-header-title {
192
- font-size: 1.6rem;
193
- font-weight: 800;
194
- letter-spacing: -0.03em;
195
- }
196
-
197
- .bl-header-sub {
198
- font-size: 0.88rem;
199
- color: #6b7280;
200
- margin-top: 4px;
201
- }
202
-
203
- .bl-header-actions {
204
- display: flex;
205
- gap: 10px;
206
- }
207
-
208
- .bl-btn {
209
- padding: 9px 20px;
210
- border-radius: 10px;
211
- font-family: inherit;
212
- font-size: 0.82rem;
213
- font-weight: 600;
214
- border: none;
215
- cursor: pointer;
216
- transition: all 0.2s;
217
- }
218
-
219
- .bl-btn-primary {
220
- background: linear-gradient(135deg, #6366f1, #818cf8);
221
- color: #fff;
222
- }
223
-
224
- .bl-btn-primary:hover {
225
- transform: translateY(-1px);
226
- box-shadow: 0 4px 20px rgba(99, 102, 241, 0.3);
227
- }
228
-
229
- .bl-btn-ghost {
230
- background: rgba(255,255,255,0.05);
231
- color: #9ca3af;
232
- border: 1px solid rgba(255,255,255,0.08);
233
- }
234
-
235
- .bl-btn-ghost:hover {
236
- background: rgba(255,255,255,0.08);
237
- color: #e5e7eb;
238
- }
239
-
240
- /* ── Stats Grid ── */
241
- .bl-stats {
242
- display: grid;
243
- grid-template-columns: repeat(4, 1fr);
244
- gap: 16px;
245
- margin-bottom: 32px;
246
- }
247
-
248
- .bl-stat-card {
249
- padding: 24px;
250
- border-radius: 16px;
251
- background: #111114;
252
- border: 1px solid rgba(255,255,255,0.06);
253
- transition: all 0.3s;
254
- animation: fade-up 0.6s ease-out both;
255
- }
256
-
257
- .bl-stat-card:nth-child(1) { animation-delay: 0.05s; }
258
- .bl-stat-card:nth-child(2) { animation-delay: 0.1s; }
259
- .bl-stat-card:nth-child(3) { animation-delay: 0.15s; }
260
- .bl-stat-card:nth-child(4) { animation-delay: 0.2s; }
261
-
262
- .bl-stat-card:hover {
263
- border-color: rgba(99, 102, 241, 0.2);
264
- transform: translateY(-2px);
265
- box-shadow: 0 8px 32px rgba(0,0,0,0.3);
266
- }
267
-
268
- .bl-stat-top {
269
- display: flex;
270
- justify-content: space-between;
271
- align-items: center;
272
- margin-bottom: 16px;
273
- }
274
-
275
- .bl-stat-icon {
276
- width: 40px; height: 40px;
277
- border-radius: 10px;
278
- background: rgba(99, 102, 241, 0.1);
279
- display: flex;
280
- align-items: center;
281
- justify-content: center;
282
- font-size: 1rem;
283
- color: #818cf8;
284
- }
285
-
286
- .bl-stat-change {
287
- font-size: 0.75rem;
288
- font-weight: 600;
289
- padding: 3px 8px;
290
- border-radius: 6px;
291
- }
292
-
293
- .bl-stat-change.up {
294
- background: rgba(34, 197, 94, 0.1);
295
- color: #4ade80;
296
- }
297
-
298
- .bl-stat-change.down {
299
- background: rgba(239, 68, 68, 0.1);
300
- color: #f87171;
301
- }
302
-
303
- .bl-stat-value {
304
- font-size: 1.8rem;
305
- font-weight: 800;
306
- letter-spacing: -0.02em;
307
- margin-bottom: 4px;
308
- }
309
-
310
- .bl-stat-label {
311
- font-size: 0.82rem;
312
- color: #6b7280;
313
- font-weight: 500;
314
- }
315
-
316
- /* ── Content Grid ── */
317
- .bl-grid {
318
- display: grid;
319
- grid-template-columns: 1fr 380px;
320
- gap: 20px;
321
- }
322
-
323
- .bl-card {
324
- border-radius: 16px;
325
- background: #111114;
326
- border: 1px solid rgba(255,255,255,0.06);
327
- padding: 24px;
328
- animation: fade-up 0.6s ease-out 0.25s both;
329
- }
330
-
331
- .bl-card-title {
332
- font-size: 1rem;
333
- font-weight: 700;
334
- margin-bottom: 20px;
335
- display: flex;
336
- justify-content: space-between;
337
- align-items: center;
338
- }
339
-
340
- .bl-card-badge {
341
- font-size: 0.7rem;
342
- padding: 4px 10px;
343
- border-radius: 6px;
344
- background: rgba(99, 102, 241, 0.1);
345
- color: #818cf8;
346
- font-weight: 600;
347
- }
348
-
349
- /* ── Chart placeholder ── */
350
- .bl-chart {
351
- height: 200px;
352
- border-radius: 12px;
353
- background: linear-gradient(180deg, rgba(99, 102, 241, 0.08) 0%, transparent 100%);
354
- border: 1px dashed rgba(99, 102, 241, 0.15);
355
- display: flex;
356
- align-items: flex-end;
357
- justify-content: space-around;
358
- padding: 20px 16px;
359
- gap: 8px;
360
- }
361
-
362
- .bl-bar {
363
- flex: 1;
364
- border-radius: 6px 6px 0 0;
365
- background: linear-gradient(180deg, #6366f1 0%, #4338ca 100%);
366
- transition: all 0.3s;
367
- min-height: 10px;
368
- position: relative;
369
- }
370
-
371
- .bl-bar:hover {
372
- filter: brightness(1.3);
373
- transform: scaleY(1.05);
374
- transform-origin: bottom;
375
- }
376
-
377
- /* ── Activity List ── */
378
- .bl-activity-item {
379
- display: flex;
380
- align-items: center;
381
- gap: 14px;
382
- padding: 14px 0;
383
- border-bottom: 1px solid rgba(255,255,255,0.04);
384
- }
385
-
386
- .bl-activity-item:last-child { border-bottom: none; }
387
-
388
- .bl-activity-avatar {
389
- width: 36px; height: 36px;
390
- border-radius: 10px;
391
- background: linear-gradient(135deg, #1e1b4b, #312e81);
392
- display: flex;
393
- align-items: center;
394
- justify-content: center;
395
- font-size: 0.65rem;
396
- font-weight: 700;
397
- color: #a5b4fc;
398
- flex-shrink: 0;
399
- }
400
-
401
- .bl-activity-info { flex: 1; }
402
-
403
- .bl-activity-user {
404
- font-size: 0.82rem;
405
- font-weight: 600;
406
- color: #e5e7eb;
407
- }
408
-
409
- .bl-activity-action {
410
- font-size: 0.78rem;
411
- color: #6b7280;
412
- margin-top: 2px;
413
- }
414
-
415
- .bl-activity-time {
416
- font-size: 0.72rem;
417
- color: #4b5563;
418
- white-space: nowrap;
419
- }
420
-
421
- .bl-online-dot {
422
- width: 8px; height: 8px;
423
- border-radius: 50%;
424
- background: #22c55e;
425
- animation: pulse-ring 2s infinite;
426
- }
427
-
428
- @media (max-width: 1024px) {
429
- .bl-sidebar { display: none; }
430
- .bl-main { margin-left: 0; }
431
- .bl-stats { grid-template-columns: repeat(2, 1fr); }
432
- .bl-grid { grid-template-columns: 1fr; }
433
- }
434
-
435
- @media (max-width: 640px) {
436
- .bl-stats { grid-template-columns: 1fr; }
437
- .bl-main { padding: 20px 16px; }
438
- }
439
- `,
440
- }}
441
- />
56
+ <div className="fd">
57
+ <style dangerouslySetInnerHTML={{ __html: `
58
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
59
+ @keyframes fu{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
60
+ .fd *{box-sizing:border-box;margin:0;padding:0;font-family:'Inter',sans-serif}
61
+ .fd{min-height:100vh;background:#f0f2f0;display:flex;color:#1a1a2e;width:100%}
62
+
63
+ /* Sidebar */
64
+ .sb{width:220px;background:#fff;border-right:1px solid #e5e7eb;padding:16px 10px;display:flex;flex-direction:column;position:fixed;top:0;bottom:0;left:0;z-index:10}
65
+ .sb-brand{display:flex;align-items:center;gap:8px;padding:8px 10px;margin-bottom:20px}
66
+ .sb-logo{width:28px;height:28px;border-radius:7px;background:linear-gradient(135deg,#16a34a,#22c55e);display:flex;align-items:center;justify-content:center;font-size:0.75rem;color:#fff;font-weight:800}
67
+ .sb-name{font-size:0.9rem;font-weight:800;letter-spacing:-0.01em}
68
+ .sb-nav{list-style:none;flex:1}
69
+ .sb-ni{display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:8px;font-size:0.78rem;font-weight:500;color:#6b7280;cursor:pointer;transition:all 0.15s;margin-bottom:1px;border:none;background:none;width:100%;text-align:left;font-family:inherit}
70
+ .sb-ni:hover{color:#16a34a;background:#f0fdf4}
71
+ .sb-ni.on{color:#fff;background:#16a34a;font-weight:600}
72
+ .sb-cta{margin-top:auto;padding:16px;border-radius:12px;background:linear-gradient(135deg,#0f3d1e,#14532d);color:#fff;text-align:center}
73
+ .sb-cta p{font-size:0.65rem;color:#86efac;margin:6px 0 10px;line-height:1.4}
74
+ .sb-cta-btn{padding:6px 16px;border-radius:6px;background:#22c55e;color:#fff;font-size:0.72rem;font-weight:600;border:none;cursor:pointer;font-family:inherit}
75
+
76
+ /* Mobile header bar */
77
+ .mob-bar{display:none;position:sticky;top:0;z-index:20;background:#fff;border-bottom:1px solid #e5e7eb;padding:10px 16px;align-items:center;gap:10px}
78
+ .mob-bar-btn{width:36px;height:36px;border-radius:8px;background:#f0fdf4;border:1px solid #dcfce7;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:1.1rem}
79
+ .mob-bar h1{font-size:1rem;font-weight:800;flex:1}
80
+ .mob-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.4);z-index:50}
81
+ .mob-overlay.show{display:block}
82
+ .sb.mob-open{display:flex!important;z-index:60}
83
+
84
+ /* Layout */
85
+ .mn{margin-left:220px;display:grid;grid-template-columns:260px 1fr 280px;min-height:100vh;width:calc(100% - 220px)}
86
+ .lp{padding:16px 14px;background:#fff;border-right:1px solid #e8ebe8;overflow-y:auto}
87
+ .cp{padding:20px;min-width:0;overflow-x:hidden}
88
+ .rp{padding:16px 14px;background:#fff;border-left:1px solid #e8ebe8;overflow-y:auto}
89
+
90
+ /* Components */
91
+ .cd{background:#fff;border-radius:12px;border:1px solid #e8ebe8;padding:16px;margin-bottom:14px;animation:fu 0.4s ease-out both}
92
+ .hdr{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;flex-wrap:wrap;gap:10px}
93
+ .hdr h1{font-size:1.2rem;font-weight:800}
94
+ .hdr-right{display:flex;align-items:center;gap:10px}
95
+ .search{padding:7px 14px;border-radius:8px;border:1px solid #e5e7eb;background:#f9fafb;font-size:0.78rem;width:220px;font-family:inherit}
96
+ .uav{width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#16a34a,#4ade80);display:flex;align-items:center;justify-content:center;font-size:0.65rem;font-weight:700;color:#fff;flex-shrink:0}
97
+
98
+ /* User Card */
99
+ .uc{background:linear-gradient(135deg,#14532d,#166534);border-radius:14px;padding:18px;color:#fff;margin-bottom:14px;position:relative;overflow:hidden}
100
+ .uc::after{content:'';position:absolute;top:-25px;right:-25px;width:100px;height:100px;border-radius:50%;background:rgba(255,255,255,0.05)}
101
+ .uc-n{font-size:0.92rem;font-weight:700;margin:8px 0 12px}
102
+ .uc-b{font-size:0.68rem;color:#86efac}
103
+ .uc-a{font-size:1.4rem;font-weight:800;margin:2px 0}
104
+ .uc-m{display:flex;gap:16px;margin-top:10px;font-size:0.68rem;color:#86efac}
105
+
106
+ /* Quick Actions */
107
+ .qa{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:14px}
108
+ .qa-i{text-align:center;padding:8px 2px;border-radius:8px;background:#f0fdf4;border:1px solid #dcfce7;cursor:pointer;transition:all 0.15s}
109
+ .qa-i:hover{background:#dcfce7;transform:translateY(-1px)}
110
+ .qa-ic{font-size:0.9rem;margin-bottom:2px}
111
+ .qa-lb{font-size:0.6rem;color:#6b7280;font-weight:500}
112
+
113
+ /* Progress bars */
114
+ .pb{height:5px;border-radius:3px;background:#e5e7eb;margin-top:6px;overflow:hidden}
115
+ .pf{height:100%;border-radius:3px;background:linear-gradient(90deg,#16a34a,#22c55e)}
116
+
117
+ /* Savings */
118
+ .sv{padding:10px 0;border-bottom:1px solid #f3f4f6}
119
+ .sv:last-child{border-bottom:none}
120
+ .sv-n{font-size:0.78rem;font-weight:600;margin-bottom:4px}
121
+ .sv-b{height:5px;border-radius:3px;background:#e5e7eb;margin:4px 0;overflow:hidden}
122
+ .sv-f{height:100%;border-radius:3px;background:#22c55e}
123
+ .sv-m{display:flex;justify-content:space-between;font-size:0.65rem;color:#9ca3af}
124
+
125
+ /* Stats */
126
+ .sts{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:16px}
127
+ .st{background:#fff;border-radius:12px;border:1px solid #e8ebe8;padding:16px;animation:fu 0.35s ease-out both}
128
+ .st:nth-child(2){animation-delay:0.05s}
129
+ .st:nth-child(3){animation-delay:0.1s}
130
+ .st-ic{width:32px;height:32px;border-radius:8px;background:#f0fdf4;display:flex;align-items:center;justify-content:center;font-size:0.8rem;margin-bottom:10px}
131
+ .st-v{font-size:1.4rem;font-weight:800;letter-spacing:-0.02em}
132
+ .st-l{font-size:0.75rem;color:#9ca3af;margin-top:2px}
133
+ .st-c{font-size:0.68rem;font-weight:600;padding:2px 6px;border-radius:4px;margin-top:6px;display:inline-block}
134
+ .st-c.up{background:#f0fdf4;color:#16a34a}
135
+ .st-c.dn{background:#fef2f2;color:#dc2626}
136
+
137
+ /* Chart */
138
+ .ch{display:flex;align-items:flex-end;gap:4px;height:160px;padding-top:6px}
139
+ .ch-c{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px}
140
+ .ch-bw{flex:1;width:100%;display:flex;gap:2px;align-items:flex-end;justify-content:center}
141
+ .ch-b{border-radius:2px 2px 0 0;min-width:6px;transition:all 0.2s}
142
+ .ch-b:hover{filter:brightness(1.15)}
143
+ .ch-b.inc{background:#16a34a}
144
+ .ch-b.exp{background:#bbf7d0}
145
+ .ch-m{font-size:0.58rem;color:#9ca3af;margin-top:3px}
146
+ .lg{display:flex;gap:12px;font-size:0.7rem;color:#6b7280}
147
+ .lg-d{width:8px;height:8px;border-radius:2px;display:inline-block;margin-right:4px}
148
+
149
+ /* Table */
150
+ .tb{width:100%;border-collapse:collapse;font-size:0.75rem}
151
+ .tb th{text-align:left;padding:8px 10px;color:#9ca3af;font-weight:500;font-size:0.68rem;border-bottom:1px solid #f3f4f6}
152
+ .tb td{padding:10px;border-bottom:1px solid #f9fafb;color:#374151}
153
+ .tb-n{font-weight:600;color:#1a1a2e;font-size:0.78rem}
154
+ .tb-c{font-size:0.68rem;color:#9ca3af}
155
+ .badge{padding:3px 8px;border-radius:5px;font-size:0.65rem;font-weight:600}
156
+
157
+ /* Donut */
158
+ .dn-w{display:flex;justify-content:center;margin:12px 0}
159
+
160
+ /* Expense list */
161
+ .ex{display:flex;align-items:center;padding:5px 0}
162
+ .ex-d{width:7px;height:7px;border-radius:50%;margin-right:7px;flex-shrink:0}
163
+ .ex-p{font-size:0.68rem;color:#9ca3af;margin-right:10px;min-width:24px;font-weight:600}
164
+ .ex-l{flex:1;font-size:0.78rem;color:#374151}
165
+ .ex-a{font-size:0.8rem;font-weight:600;text-align:right}
166
+
167
+ /* Activity */
168
+ .ac{display:flex;gap:8px;padding:6px 0}
169
+ .ac-d{width:7px;height:7px;border-radius:50%;margin-top:5px;flex-shrink:0}
170
+ .ac-t{flex:1;font-size:0.75rem;color:#374151;line-height:1.4}
171
+ .ac-u{font-weight:600;color:#1a1a2e}
172
+ .ac-tm{font-size:0.65rem;color:#9ca3af;margin-top:1px}
173
+
174
+ .stl{font-size:0.85rem;font-weight:700;margin-bottom:10px;display:flex;justify-content:space-between;align-items:center}
175
+ .stl span{font-size:0.68rem;color:#16a34a;font-weight:500;cursor:pointer}
176
+ .sub{font-size:0.68rem;color:#9ca3af}
177
+ .big{font-size:1.2rem;font-weight:800;margin-bottom:8px}
178
+
179
+ /* ── Responsive ── */
180
+
181
+ /* Large: hide right panel */
182
+ @media(max-width:1400px){
183
+ .mn{grid-template-columns:260px 1fr}
184
+ .rp{display:none}
185
+ }
186
+
187
+ /* Medium: hide left panel too, only center */
188
+ @media(max-width:1100px){
189
+ .mn{grid-template-columns:1fr}
190
+ .lp{display:none}
191
+ .sts{grid-template-columns:repeat(3,1fr)}
192
+ }
193
+
194
+ /* Tablet: hide sidebar, show mobile header */
195
+ @media(max-width:768px){
196
+ .sb{display:none}
197
+ .mn{margin-left:0;width:100%}
198
+ .mob-bar{display:flex}
199
+ .cp{padding:16px}
200
+ .sts{grid-template-columns:repeat(2,1fr)}
201
+ .search{width:140px}
202
+ .hdr{flex-wrap:wrap}
203
+ .hdr h1{display:none}
204
+ .tb th:nth-child(4),.tb td:nth-child(4){display:none}
205
+ }
206
+
207
+ /* Mobile: single column everything */
208
+ @media(max-width:480px){
209
+ .sts{grid-template-columns:1fr}
210
+ .cp{padding:12px}
211
+ .cd{padding:12px}
212
+ .hdr-right{flex-wrap:wrap}
213
+ .search{width:100%}
214
+ .st-v{font-size:1.1rem}
215
+ .ch{height:120px}
216
+ .tb th:nth-child(3),.tb td:nth-child(3){display:none}
217
+ }
218
+ `}} />
442
219
 
443
220
  {/* Sidebar */}
444
- <aside className="bl-sidebar">
445
- <div className="bl-sidebar-brand">
446
- <div className="bl-sidebar-logo">🌸</div>
447
- <div className="bl-sidebar-name">
448
- Blumen
449
- <span>Dashboard</span>
450
- </div>
221
+ <aside className="sb">
222
+ <div className="sb-brand">
223
+ <div className="sb-logo">B</div>
224
+ <div className="sb-name">BLUMEN</div>
451
225
  </div>
452
-
453
- <nav className="bl-nav">
454
- {navItems.map((item) => (
455
- <button
456
- key={item.id}
457
- className={`bl-nav-item ${activeNav === item.id ? "active" : ""}`}
458
- onClick={() => setActiveNav(item.id)}
459
- >
460
- <span className="bl-nav-icon">{item.icon}</span>
461
- {item.label}
226
+ <nav className="sb-nav">
227
+ {nav.map(n => (
228
+ <button key={n.id} className={`sb-ni ${activeNav === n.id ? "on" : ""}`} onClick={() => setActiveNav(n.id)}>
229
+ {n.label}
462
230
  </button>
463
231
  ))}
464
232
  </nav>
465
-
466
- <div className="bl-sidebar-footer">
467
- <div className="bl-avatar">JD</div>
468
- <div>
469
- <div className="bl-user-name">Jane Doe</div>
470
- <div className="bl-user-role">Admin</div>
471
- </div>
233
+ <div className="sb-cta">
234
+ <div style={{ fontSize: "1.5rem" }}>🌸</div>
235
+ <p>Gain full access to your finances with detailed analytics</p>
236
+ <button className="sb-cta-btn">Get Pro</button>
472
237
  </div>
473
238
  </aside>
474
239
 
475
- {/* Main Content */}
476
- <main className="bl-main">
477
- <div className="bl-header">
478
- <div>
479
- <h1 className="bl-header-title">Dashboard</h1>
480
- <p className="bl-header-sub">Welcome back. Here's what's happening today.</p>
240
+ {/* Mobile header bar */}
241
+ <div className="mob-bar">
242
+ <div className="mob-bar-btn" onClick={() => setActiveNav(activeNav)}>☰</div>
243
+ <h1>Dashboard</h1>
244
+ <div className="uav">AF</div>
245
+ </div>
246
+
247
+ <div className="mn">
248
+ {/* Left Panel */}
249
+ <div className="lp">
250
+ <div className="uc">
251
+ <div style={{ fontSize: "1.2rem" }}>🌸</div>
252
+ <div className="uc-n">Andrew Forbist</div>
253
+ <div className="uc-b">Balance Amount</div>
254
+ <div className="uc-a">$562,000</div>
255
+ <div className="uc-m"><span>EXP 11/29</span><span>CVV 323</span></div>
481
256
  </div>
482
- <div className="bl-header-actions">
483
- <button className="bl-btn bl-btn-ghost">Export</button>
484
- <button className="bl-btn bl-btn-primary">+ New Project</button>
257
+
258
+ <div className="qa">
259
+ {[["⊕","Top Up"],["⇄","Transfer"],["↗","Request"],["◷","History"]].map(([ic,lb]) => (
260
+ <div key={lb} className="qa-i"><div className="qa-ic">{ic}</div><div className="qa-lb">{lb}</div></div>
261
+ ))}
262
+ </div>
263
+
264
+ <div className="cd">
265
+ <div className="stl">Daily Limit</div>
266
+ <div style={{ fontSize: "0.78rem", fontWeight: 600 }}>$2,500.00 <span className="sub">spent of $20,000.00</span></div>
267
+ <div className="pb"><div className="pf" style={{ width: "12.5%" }} /></div>
268
+ <div style={{ textAlign: "right", fontSize: "0.62rem", color: "#9ca3af", marginTop: "3px" }}>12.5%</div>
485
269
  </div>
486
- </div>
487
270
 
488
- {/* Stats Row */}
489
- <div className="bl-stats">
490
- {stats.map((stat) => (
491
- <div key={stat.label} className="bl-stat-card">
492
- <div className="bl-stat-top">
493
- <div className="bl-stat-icon">{stat.icon}</div>
494
- <span className={`bl-stat-change ${stat.up ? "up" : "down"}`}>
495
- {stat.change}
496
- </span>
271
+ <div className="cd">
272
+ <div className="stl">Saving Plans <span>+ Add Plan</span></div>
273
+ <div className="sub">Total Savings</div>
274
+ <div className="big">$84,500</div>
275
+ {funds.map(f => (
276
+ <div key={f.name} className="sv">
277
+ <div className="sv-n">{f.name}</div>
278
+ <div className="sv-b"><div className="sv-f" style={{ width: `${f.pct}%` }} /></div>
279
+ <div className="sv-m"><span>{f.saved} {f.pct}%</span><span>Target: {f.target}</span></div>
497
280
  </div>
498
- <div className="bl-stat-value">{stat.value}</div>
499
- <div className="bl-stat-label">{stat.label}</div>
500
- </div>
501
- ))}
281
+ ))}
282
+ </div>
502
283
  </div>
503
284
 
504
- {/* Content Grid */}
505
- <div className="bl-grid">
506
- {/* Chart Card */}
507
- <div className="bl-card">
508
- <div className="bl-card-title">
509
- Revenue Overview
510
- <span className="bl-card-badge">Last 7 days</span>
285
+ {/* Center */}
286
+ <div className="cp">
287
+ <div className="hdr">
288
+ <h1>Dashboard</h1>
289
+ <div className="hdr-right">
290
+ <input className="search" placeholder="Search placeholder" />
291
+ <div className="uav">AF</div>
292
+ <span style={{ fontSize: "0.82rem", fontWeight: 600 }}>Andrew Forbist</span>
511
293
  </div>
512
- <div className="bl-chart">
513
- {[65, 45, 80, 55, 90, 70, 85].map((h, i) => (
514
- <div
515
- key={i}
516
- className="bl-bar"
517
- style={{ height: `${h}%`, opacity: 0.6 + (h / 300) }}
518
- />
294
+ </div>
295
+
296
+ <div className="sts">
297
+ {stats.map(s => (
298
+ <div key={s.label} className="st">
299
+ <div className="st-ic">💰</div>
300
+ <div className="st-v">{s.value}</div>
301
+ <div className="st-l">{s.label}</div>
302
+ <span className={`st-c ${s.up ? "up" : "dn"}`}>{s.change}</span>
303
+ </div>
304
+ ))}
305
+ </div>
306
+
307
+ <div className="cd" style={{ animationDelay: "0.12s" }}>
308
+ <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
309
+ <div>
310
+ <div className="stl" style={{ marginBottom: 4 }}>Cashflow</div>
311
+ <div className="sub">Total Balance</div>
312
+ <div style={{ fontSize: "1.2rem", fontWeight: 800, margin: "2px 0 10px" }}>$562,000</div>
313
+ </div>
314
+ <div className="lg">
315
+ <span><span className="lg-d" style={{ background: "#16a34a" }} />Income</span>
316
+ <span><span className="lg-d" style={{ background: "#bbf7d0" }} />Expense</span>
317
+ </div>
318
+ </div>
319
+ <div className="ch">
320
+ {bars.map(d => (
321
+ <div key={d.m} className="ch-c">
322
+ <div className="ch-bw">
323
+ <div className="ch-b inc" style={{ height: `${d.i * 1.6}px` }} />
324
+ <div className="ch-b exp" style={{ height: `${d.e * 1.6}px` }} />
325
+ </div>
326
+ <div className="ch-m">{d.m}</div>
327
+ </div>
519
328
  ))}
520
329
  </div>
521
330
  </div>
522
331
 
523
- {/* Activity Feed */}
524
- <div className="bl-card">
525
- <div className="bl-card-title">
526
- Recent Activity
527
- <div className="bl-online-dot" />
332
+ <div className="cd" style={{ animationDelay: "0.2s" }}>
333
+ <div className="stl">Recent Transactions</div>
334
+ <table className="tb">
335
+ <thead><tr><th>Transaction Name</th><th>Date</th><th>Amount</th><th>Note</th><th>Status</th></tr></thead>
336
+ <tbody>
337
+ {txns.map(t => (
338
+ <tr key={t.name}>
339
+ <td><div className="tb-n">{t.name}</div><div className="tb-c">{t.cat}</div></td>
340
+ <td>{t.date}</td>
341
+ <td>{t.amt}</td>
342
+ <td style={{ color: "#9ca3af", fontSize: "0.65rem" }}>{t.note}</td>
343
+ <td><span className="badge" style={{ background: sc[t.status].bg, color: sc[t.status].fg }}>{t.status}</span></td>
344
+ </tr>
345
+ ))}
346
+ </tbody>
347
+ </table>
348
+ </div>
349
+ </div>
350
+
351
+ {/* Right Panel */}
352
+ <div className="rp">
353
+ <div className="cd">
354
+ <div className="stl">Statistic</div>
355
+ <div className="dn-w">
356
+ <svg width="120" height="120" viewBox="0 0 120 120">
357
+ <circle cx="60" cy="60" r="46" fill="none" stroke="#e5e7eb" strokeWidth="12" />
358
+ <circle cx="60" cy="60" r="46" fill="none" stroke="#16a34a" strokeWidth="12" strokeDasharray="289" strokeDashoffset="72" strokeLinecap="round" transform="rotate(-90 60 60)" />
359
+ <circle cx="60" cy="60" r="46" fill="none" stroke="#4ade80" strokeWidth="12" strokeDasharray="289" strokeDashoffset="246" strokeLinecap="round" transform="rotate(150 60 60)" />
360
+ <text x="60" y="55" textAnchor="middle" fill="#9ca3af" fontSize="7" fontFamily="Inter">Total Expense</text>
361
+ <text x="60" y="70" textAnchor="middle" fill="#1a1a2e" fontSize="14" fontWeight="800" fontFamily="Inter">$3,500</text>
362
+ </svg>
528
363
  </div>
529
- {recentActivity.map((item) => (
530
- <div key={item.user} className="bl-activity-item">
531
- <div className="bl-activity-avatar">{item.avatar}</div>
532
- <div className="bl-activity-info">
533
- <div className="bl-activity-user">{item.user}</div>
534
- <div className="bl-activity-action">{item.action}</div>
535
- </div>
536
- <div className="bl-activity-time">{item.time}</div>
364
+ {expenses.map(e => (
365
+ <div key={e.label} className="ex">
366
+ <span className="ex-d" style={{ background: e.c }} />
367
+ <span className="ex-p">{e.pct}</span>
368
+ <span className="ex-l">{e.label}</span>
369
+ <span className="ex-a">{e.amt}</span>
370
+ </div>
371
+ ))}
372
+ </div>
373
+
374
+ <div className="cd" style={{ animationDelay: "0.1s" }}>
375
+ <div className="stl">Recent Activity</div>
376
+ <div style={{ fontSize: "0.68rem", fontWeight: 600, color: "#9ca3af", marginBottom: "6px" }}>Today</div>
377
+ {acts.map(a => (
378
+ <div key={a.u} className="ac">
379
+ <span className="ac-d" style={{ background: a.c }} />
380
+ <div><div className="ac-t"><span className="ac-u">{a.u}</span> {a.a}</div><div className="ac-tm">{a.t}</div></div>
381
+ </div>
382
+ ))}
383
+ <div style={{ fontSize: "0.68rem", fontWeight: 600, color: "#9ca3af", margin: "10px 0 6px" }}>Yesterday</div>
384
+ {actsY.map(a => (
385
+ <div key={a.u} className="ac">
386
+ <span className="ac-d" style={{ background: a.c }} />
387
+ <div><div className="ac-t"><span className="ac-u">{a.u}</span> {a.a}</div><div className="ac-tm">{a.t}</div></div>
537
388
  </div>
538
389
  ))}
539
390
  </div>
540
391
  </div>
541
- </main>
392
+ </div>
542
393
  </div>
543
394
  );
544
395
  };