1
2
3
4
5:root {
6
7 --bg-primary: #0b0f19;
8 --bg-secondary: #111827;
9 --bg-card: #1f2937;
10 --bg-card-hover: #374151;
11 --bg-glass: rgba(31, 41, 55, 0.7);
12 --border-color: rgba(255, 255, 255, 0.08);
13 --border-color-strong: rgba(255, 255, 255, 0.15);
14
15 --text-primary: #f9fafb;
16 --text-secondary: #9ca3af;
17 --text-muted: #6b7280;
18
19
20 --primary: #6366f1;
21 --primary-hover: #4f46e5;
22 --primary-light: rgba(99, 102, 241, 0.15);
23
24 --income-green: #10b981;
25 --income-green-bg: rgba(16, 185, 129, 0.12);
26
27 --expense-rose: #f43f5e;
28 --expense-rose-bg: rgba(244, 63, 94, 0.12);
29
30 --warning-amber: #f59e0b;
31 --warning-amber-bg: rgba(245, 158, 11, 0.12);
32
33 --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
34 --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
35 --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.3);
36 --radius-sm: 6px;
37 --radius-md: 10px;
38 --radius-lg: 16px;
39 --radius-full: 9999px;
40
41 --transition-fast: all 0.15s ease-in-out;
42 --transition-normal: all 0.25s ease-in-out;
43}
44
45[data-theme="light"] {
46 --bg-primary: #f8fafc;
47 --bg-secondary: #ffffff;
48 --bg-card: #ffffff;
49 --bg-card-hover: #f1f5f9;
50 --bg-glass: rgba(255, 255, 255, 0.8);
51 --border-color: #e2e8f0;
52 --border-color-strong: #cbd5e1;
53
54 --text-primary: #0f172a;
55 --text-secondary: #475569;
56 --text-muted: #94a3b8;
57
58 --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.05);
59 --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.08);
60 --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
61}
62
63
64* {
65 box-sizing: border-box;
66 margin: 0;
67 padding: 0;
68}
69
70body {
71 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
72 background-color: var(--bg-primary);
73 color: var(--text-primary);
74 line-height: 1.5;
75 min-height: 100vh;
76 transition: background-color var(--transition-normal), color var(--transition-normal);
77}
78
79.app-container {
80 max-width: 1380px;
81 margin: 0 auto;
82 padding: 24px;
83}
84
85
86.navbar {
87 display: flex;
88 justify-content: space-between;
89 align-items: center;
90 padding: 16px 24px;
91 background: var(--bg-glass);
92 backdrop-filter: blur(12px);
93 border: 1px solid var(--border-color);
94 border-radius: var(--radius-lg);
95 margin-bottom: 24px;
96 box-shadow: var(--shadow-md);
97}
98
99.brand {
100 display: flex;
101 align-items: center;
102 gap: 12px;
103}
104
105.brand-icon {
106 width: 40px;
107 height: 40px;
108 background: linear-gradient(135deg, var(--primary), #8b5cf6);
109 border-radius: var(--radius-md);
110 display: flex;
111 align-items: center;
112 justify-content: center;
113 font-size: 20px;
114 font-weight: bold;
115 color: #fff;
116 box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
117}
118
119.brand-text h1 {
120 font-size: 1.25rem;
121 font-weight: 700;
122 letter-spacing: -0.02em;
123}
124
125.brand-text p {
126 font-size: 0.8rem;
127 color: var(--text-secondary);
128}
129
130.nav-actions {
131 display: flex;
132 align-items: center;
133 gap: 12px;
134}
135
136
137.btn {
138 display: inline-flex;
139 align-items: center;
140 justify-content: center;
141 gap: 8px;
142 padding: 9px 16px;
143 font-size: 0.875rem;
144 font-weight: 600;
145 border-radius: var(--radius-md);
146 border: 1px solid transparent;
147 cursor: pointer;
148 transition: var(--transition-fast);
149 white-space: nowrap;
150}
151
152.btn-primary {
153 background: var(--primary);
154 color: #ffffff;
155 box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
156}
157
158.btn-primary:hover {
159 background: var(--primary-hover);
160 transform: translateY(-1px);
161}
162
163.btn-secondary {
164 background: var(--bg-secondary);
165 color: var(--text-primary);
166 border-color: var(--border-color-strong);
167}
168
169.btn-secondary:hover {
170 background: var(--bg-card-hover);
171}
172
173.btn-danger {
174 background: var(--expense-rose-bg);
175 color: var(--expense-rose);
176 border-color: rgba(244, 63, 94, 0.2);
177}
178
179.btn-danger:hover {
180 background: rgba(244, 63, 94, 0.25);
181}
182
183.btn-icon {
184 padding: 8px;
185 border-radius: var(--radius-md);
186 background: var(--bg-secondary);
187 color: var(--text-primary);
188 border: 1px solid var(--border-color);
189 cursor: pointer;
190 display: inline-flex;
191 align-items: center;
192 justify-content: center;
193}
194
195.btn-icon:hover {
196 background: var(--bg-card-hover);
197}
198
199
200.summary-grid {
201 display: grid;
202 grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
203 gap: 20px;
204 margin-bottom: 24px;
205}
206
207.kpi-card {
208 background: var(--bg-card);
209 border: 1px solid var(--border-color);
210 border-radius: var(--radius-lg);
211 padding: 20px;
212 box-shadow: var(--shadow-sm);
213 display: flex;
214 flex-direction: column;
215 justify-content: space-between;
216 transition: var(--transition-normal);
217}
218
219.kpi-card:hover {
220 border-color: var(--border-color-strong);
221 transform: translateY(-2px);
222 box-shadow: var(--shadow-md);
223}
224
225.kpi-header {
226 display: flex;
227 justify-content: space-between;
228 align-items: center;
229 margin-bottom: 12px;
230}
231
232.kpi-title {
233 font-size: 0.85rem;
234 font-weight: 600;
235 color: var(--text-secondary);
236 text-transform: uppercase;
237 letter-spacing: 0.05em;
238}
239
240.kpi-icon-badge {
241 width: 36px;
242 height: 36px;
243 border-radius: var(--radius-md);
244 display: flex;
245 align-items: center;
246 justify-content: center;
247 font-size: 1.1rem;
248}
249
250.kpi-value {
251 font-size: 1.75rem;
252 font-weight: 800;
253 letter-spacing: -0.03em;
254 margin-bottom: 4px;
255}
256
257.kpi-subtext {
258 font-size: 0.8rem;
259 color: var(--text-muted);
260}
261
262
263.dashboard-grid {
264 display: grid;
265 grid-template-columns: 2fr 1fr;
266 gap: 24px;
267 margin-bottom: 24px;
268}
269
270@media (max-width: 1024px) {
271 .dashboard-grid {
272 grid-template-columns: 1fr;
273 }
274}
275
276.card {
277 background: var(--bg-card);
278 border: 1px solid var(--border-color);
279 border-radius: var(--radius-lg);
280 padding: 24px;
281 box-shadow: var(--shadow-sm);
282}
283
284.card-header {
285 display: flex;
286 justify-content: space-between;
287 align-items: center;
288 margin-bottom: 20px;
289}
290
291.card-title {
292 font-size: 1.1rem;
293 font-weight: 700;
294 display: flex;
295 align-items: center;
296 gap: 8px;
297}
298
299
300.chart-container {
301 position: relative;
302 width: 100%;
303 height: 300px;
304}
305
306
307.budget-list {
308 display: flex;
309 flex-direction: column;
310 gap: 16px;
311 max-height: 320px;
312 overflow-y: auto;
313 padding-right: 4px;
314}
315
316.budget-item {
317 display: flex;
318 flex-direction: column;
319 gap: 6px;
320}
321
322.budget-item-header {
323 display: flex;
324 justify-content: space-between;
325 font-size: 0.875rem;
326 font-weight: 600;
327}
328
329.budget-item-cat {
330 display: flex;
331 align-items: center;
332 gap: 6px;
333}
334
335.budget-item-values {
336 color: var(--text-secondary);
337}
338
339.budget-progress-track {
340 width: 100%;
341 height: 10px;
342 background: var(--bg-secondary);
343 border-radius: var(--radius-full);
344 overflow: hidden;
345 position: relative;
346}
347
348.budget-progress-fill {
349 height: 100%;
350 border-radius: var(--radius-full);
351 transition: width 0.4s ease-out, background-color 0.25s ease;
352}
353
354.budget-status-tag {
355 font-size: 0.72rem;
356 padding: 2px 8px;
357 border-radius: var(--radius-full);
358 font-weight: 600;
359}
360
361
362.transactions-section {
363 background: var(--bg-card);
364 border: 1px solid var(--border-color);
365 border-radius: var(--radius-lg);
366 padding: 24px;
367 box-shadow: var(--shadow-sm);
368}
369
370.filter-toolbar {
371 display: flex;
372 flex-wrap: wrap;
373 gap: 12px;
374 align-items: center;
375 justify-content: space-between;
376 margin-bottom: 20px;
377}
378
379.filter-group {
380 display: flex;
381 flex-wrap: wrap;
382 align-items: center;
383 gap: 10px;
384}
385
386.input-search {
387 padding: 8px 14px;
388 border-radius: var(--radius-md);
389 border: 1px solid var(--border-color-strong);
390 background: var(--bg-secondary);
391 color: var(--text-primary);
392 font-size: 0.875rem;
393 min-width: 220px;
394}
395
396.input-search:focus {
397 outline: 2px solid var(--primary);
398 border-color: transparent;
399}
400
401.select-filter, .input-date {
402 padding: 8px 12px;
403 border-radius: var(--radius-md);
404 border: 1px solid var(--border-color-strong);
405 background: var(--bg-secondary);
406 color: var(--text-primary);
407 font-size: 0.875rem;
408}
409
410
411.table-responsive {
412 width: 100%;
413 overflow-x: auto;
414}
415
416.transactions-table {
417 width: 100%;
418 border-collapse: collapse;
419 text-align: left;
420 font-size: 0.875rem;
421}
422
423.transactions-table th {
424 padding: 12px 16px;
425 color: var(--text-secondary);
426 font-weight: 600;
427 border-bottom: 1px solid var(--border-color);
428 text-transform: uppercase;
429 font-size: 0.75rem;
430 letter-spacing: 0.04em;
431}
432
433.transactions-table td {
434 padding: 14px 16px;
435 border-bottom: 1px solid var(--border-color);
436 vertical-align: middle;
437}
438
439.transactions-table tbody tr:hover {
440 background: var(--bg-card-hover);
441}
442
443.badge {
444 display: inline-flex;
445 align-items: center;
446 gap: 4px;
447 padding: 4px 10px;
448 border-radius: var(--radius-full);
449 font-size: 0.75rem;
450 font-weight: 600;
451}
452
453.badge-income {
454 background: var(--income-green-bg);
455 color: var(--income-green);
456}
457
458.badge-expense {
459 background: var(--expense-rose-bg);
460 color: var(--expense-rose);
461}
462
463.badge-category {
464 background: var(--primary-light);
465 color: var(--primary);
466}
467
468.amount-income {
469 color: var(--income-green);
470 font-weight: 700;
471}
472
473.amount-expense {
474 color: var(--text-primary);
475 font-weight: 600;
476}
477
478.action-buttons {
479 display: flex;
480 align-items: center;
481 gap: 6px;
482}
483
484.action-btn {
485 background: transparent;
486 border: none;
487 color: var(--text-secondary);
488 cursor: pointer;
489 padding: 6px;
490 border-radius: var(--radius-sm);
491 transition: var(--transition-fast);
492}
493
494.action-btn:hover {
495 background: var(--bg-secondary);
496 color: var(--text-primary);
497}
498
499.action-btn.delete:hover {
500 color: var(--expense-rose);
501}
502
503
504.modal-backdrop {
505 position: fixed;
506 top: 0;
507 left: 0;
508 width: 100vw;
509 height: 100vh;
510 background: rgba(0, 0, 0, 0.65);
511 backdrop-filter: blur(6px);
512 display: flex;
513 align-items: center;
514 justify-content: center;
515 z-index: 1000;
516 opacity: 0;
517 pointer-events: none;
518 transition: opacity 0.2s ease;
519}
520
521.modal-backdrop.active {
522 opacity: 1;
523 pointer-events: auto;
524}
525
526.modal {
527 background: var(--bg-secondary);
528 border: 1px solid var(--border-color-strong);
529 border-radius: var(--radius-lg);
530 width: 100%;
531 max-width: 500px;
532 padding: 28px;
533 box-shadow: var(--shadow-lg);
534 transform: translateY(20px);
535 transition: transform 0.25s ease;
536}
537
538.modal-backdrop.active .modal {
539 transform: translateY(0);
540}
541
542.modal-header {
543 display: flex;
544 justify-content: space-between;
545 align-items: center;
546 margin-bottom: 20px;
547}
548
549.modal-title {
550 font-size: 1.2rem;
551 font-weight: 700;
552}
553
554.modal-close {
555 background: transparent;
556 border: none;
557 color: var(--text-secondary);
558 font-size: 1.5rem;
559 cursor: pointer;
560 line-height: 1;
561}
562
563.form-group {
564 margin-bottom: 16px;
565}
566
567.form-label {
568 display: block;
569 font-size: 0.85rem;
570 font-weight: 600;
571 color: var(--text-secondary);
572 margin-bottom: 6px;
573}
574
575.form-input, .form-select, .form-textarea {
576 width: 100%;
577 padding: 10px 14px;
578 border-radius: var(--radius-md);
579 border: 1px solid var(--border-color-strong);
580 background: var(--bg-card);
581 color: var(--text-primary);
582 font-size: 0.9rem;
583}
584
585.form-input:focus, .form-select:focus, .form-textarea:focus {
586 outline: 2px solid var(--primary);
587 border-color: transparent;
588}
589
590.form-row {
591 display: grid;
592 grid-template-columns: 1fr 1fr;
593 gap: 16px;
594}
595
596.form-actions {
597 display: flex;
598 justify-content: flex-end;
599 gap: 12px;
600 margin-top: 24px;
601}
602
603
604.shortcut-list {
605 display: grid;
606 grid-template-columns: 1fr 1fr;
607 gap: 12px;
608 font-size: 0.875rem;
609}
610
611.shortcut-item {
612 display: flex;
613 justify-content: space-between;
614 align-items: center;
615 padding: 8px 12px;
616 background: var(--bg-card);
617 border-radius: var(--radius-md);
618 border: 1px solid var(--border-color);
619}
620
621kbd {
622 background: var(--bg-secondary);
623 border: 1px solid var(--border-color-strong);
624 border-radius: var(--radius-sm);
625 padding: 2px 6px;
626 font-family: monospace;
627 font-size: 0.75rem;
628 box-shadow: var(--shadow-sm);
629}
630
631
632.toast-container {
633 position: fixed;
634 bottom: 24px;
635 right: 24px;
636 z-index: 2000;
637 display: flex;
638 flex-direction: column;
639 gap: 10px;
640}
641
642.toast {
643 background: var(--bg-card);
644 border: 1px solid var(--border-color-strong);
645 color: var(--text-primary);
646 padding: 12px 18px;
647 border-radius: var(--radius-md);
648 box-shadow: var(--shadow-lg);
649 font-size: 0.875rem;
650 font-weight: 500;
651 display: flex;
652 align-items: center;
653 gap: 10px;
654 animation: slideIn 0.3s ease;
655}
656
657@keyframes slideIn {
658 from {
659 transform: translateX(100%);
660 opacity: 0;
661 }
662 to {
663 transform: translateX(0);
664 opacity: 1;
665 }
666}
667
Discussion
No comments yet. Start the discussion. Recorded by @patrick-toulme.