mbkbucket 3.5.1 → 3.6.0

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/.env.example +14 -14
  2. package/.mbkbucket.config.example.json +14 -14
  3. package/LICENSE +20 -20
  4. package/README.md +377 -350
  5. package/index.js +30 -30
  6. package/lib/cli.js +649 -649
  7. package/lib/public/bucketadmin.css +1420 -1420
  8. package/lib/public/bucketadmin.js +1229 -1229
  9. package/lib/public/mbkbucket-helper-demo.html +1184 -1184
  10. package/lib/public/mbkbucket-helper.css +1235 -1235
  11. package/lib/public/mbkbucket-helper.js +1557 -1557
  12. package/lib/src/app.js +109 -109
  13. package/lib/src/cli/auth-helper.js +150 -150
  14. package/lib/src/config/index.js +112 -112
  15. package/lib/src/config/validation.js +73 -73
  16. package/lib/src/controllers/api.controller.js +410 -410
  17. package/lib/src/controllers/dashboard.controller.js +48 -48
  18. package/lib/src/controllers/info.controller.js +34 -34
  19. package/lib/src/controllers/view.controller.js +233 -233
  20. package/lib/src/middleware/async-handler.js +23 -23
  21. package/lib/src/middleware/bucket-resolver.js +37 -37
  22. package/lib/src/middleware/error-handler.js +54 -54
  23. package/lib/src/middleware/rate-limiter.js +22 -22
  24. package/lib/src/middleware/security.js +27 -27
  25. package/lib/src/routes/api.routes.js +54 -40
  26. package/lib/src/routes/index.js +40 -21
  27. package/lib/src/routes/info.routes.js +9 -9
  28. package/lib/src/routes/view.routes.js +25 -20
  29. package/lib/src/services/s3.service.js +603 -603
  30. package/lib/src/utils/errors.js +54 -54
  31. package/lib/src/utils/helpers.js +251 -251
  32. package/lib/src/utils/logger.js +17 -17
  33. package/package.json +83 -83
  34. package/views/bucket.handlebars +196 -196
  35. package/views/bucketadmin_alerts.handlebars +15 -15
  36. package/views/bucketadmin_delete_modal.handlebars +36 -36
  37. package/views/bucketadmin_filelist_skeleton.handlebars +32 -32
  38. package/views/bucketadmin_newfolder_modal.handlebars +29 -29
  39. package/views/bucketadmin_preview_modal.handlebars +40 -40
  40. package/views/bucketadmin_upload_modal.handlebars +54 -54
  41. package/views/bucketadmincontent.handlebars +141 -141
  42. package/views/mbkbucket_info.handlebars +232 -232
@@ -1,1420 +1,1420 @@
1
- /* ==========================================================================
2
- MBKBucket File Manager - Original Theme Palette + Gentelella v4 Layout
3
- ========================================================================== */
4
-
5
- :root {
6
- --primary-color-ml: #0f766e;
7
- --primary-light-color-ml: #d7f4ee;
8
- --primary-dark-color-ml: #0b4f4a;
9
- --secondary-color-ml: #1f8f84;
10
- --dark-color-ml: #1f2a2a;
11
- --light-color-ml: #f4f7f3;
12
- --gray-color-ml: #667c79;
13
- --gray-light-color-ml: #dce8e3;
14
- --danger-color-ml: #dc2626;
15
- --warning-color-ml: #d97706;
16
- --success-color-ml: #16a34a;
17
- --info-color-ml: #3b82f6;
18
-
19
- --primary: var(--primary-color-ml);
20
- --primary-lt: var(--primary-light-color-ml);
21
- --primary-dk: var(--primary-dark-color-ml);
22
- --primary-hover: #0d635c;
23
-
24
- --body-bg: var(--light-color-ml);
25
- --bg-surface: rgba(255, 255, 255, 0.82);
26
- --bg-surface-secondary: rgba(244, 247, 243, 0.85);
27
- --bg-surface-tertiary: #e2ede8;
28
-
29
- --border-color: rgba(15, 118, 110, 0.16);
30
- --border-color-light: rgba(15, 118, 110, 0.08);
31
-
32
- --text: var(--dark-color-ml);
33
- --text-secondary: #425855;
34
- --text-muted: var(--gray-color-ml);
35
- --text-disabled: #a0b2af;
36
-
37
- --blue: #066fd1;
38
- --azure: #1f8f84;
39
- --green: #16a34a;
40
- --yellow: #d97706;
41
- --orange: #ea580c;
42
- --red: #dc2626;
43
- --purple: #7c3aed;
44
- --cyan: #0f766e;
45
-
46
- --green-lt: rgba(22, 163, 74, 0.12);
47
- --red-lt: rgba(220, 38, 38, 0.1);
48
- --yellow-lt: rgba(217, 119, 6, 0.12);
49
- --blue-lt: rgba(6, 111, 209, 0.1);
50
- --azure-lt: rgba(31, 143, 132, 0.12);
51
- --purple-lt: rgba(124, 58, 237, 0.1);
52
- --cyan-lt: rgba(15, 118, 110, 0.12);
53
-
54
- --radius-sm: 6px;
55
- --radius: 8px;
56
- --radius-lg: 14px;
57
- --radius-xl: 18px;
58
-
59
- --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.04);
60
- --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
61
- --shadow-md: 0 10px 15px -3px rgba(15, 118, 110, 0.08), 0 4px 6px -2px rgba(0, 0, 0, 0.04);
62
- --shadow-lg: 0 20px 25px -5px rgba(15, 118, 110, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
63
- --shadow-dropdown: 0 12px 30px rgba(15, 42, 42, 0.14), 0 4px 10px rgba(0, 0, 0, 0.05);
64
-
65
- --font: "IBM Plex Sans", "Segoe UI", sans-serif;
66
- --font-headings: "Sora", "Segoe UI", sans-serif;
67
- --font-mono: 'JetBrains Mono', 'SF Mono', Consolas, monospace;
68
- }
69
-
70
- /* Base Layout & Page Header */
71
- .page-wrapper {
72
- max-width: 1600px;
73
- margin: 0 auto;
74
- width: 100%;
75
- }
76
-
77
- .page-header {
78
- display: flex;
79
- align-items: center;
80
- justify-content: space-between;
81
- margin-bottom: 1.2rem;
82
- padding: 0.9rem 1.3rem;
83
- border: 1px solid rgba(255, 255, 255, 0.9);
84
- border-radius: 1rem;
85
- background: rgba(255, 255, 255, 0.74);
86
- backdrop-filter: blur(10px);
87
- box-shadow: 0 12px 34px rgba(15, 23, 42, 0.05);
88
- }
89
-
90
- .page-header-row {
91
- display: flex;
92
- align-items: center;
93
- justify-content: space-between;
94
- width: 100%;
95
- gap: 1rem;
96
- }
97
-
98
- .page-pretitle {
99
- font-size: 11px;
100
- font-weight: 700;
101
- text-transform: uppercase;
102
- letter-spacing: 0.6px;
103
- color: var(--primary-color-ml);
104
- margin-bottom: 2px;
105
- }
106
-
107
- .page-title {
108
- font-family: var(--font-headings);
109
- font-size: 1.45rem;
110
- font-weight: 700;
111
- color: var(--dark-color-ml);
112
- margin: 0;
113
- line-height: 1.2;
114
- }
115
-
116
- .page-actions {
117
- display: flex;
118
- align-items: center;
119
- gap: 0.65rem;
120
- }
121
-
122
- /* Button System */
123
- .btn {
124
- display: inline-flex;
125
- align-items: center;
126
- justify-content: center;
127
- gap: 0.45rem;
128
- font-family: var(--font);
129
- font-size: 13px;
130
- font-weight: 600;
131
- line-height: 1.4;
132
- padding: 7px 15px;
133
- border-radius: var(--radius);
134
- border: 1px solid transparent;
135
- cursor: pointer;
136
- transition: all 0.15s ease-in-out;
137
- text-decoration: none;
138
- white-space: nowrap;
139
- }
140
-
141
- .btn svg {
142
- flex-shrink: 0;
143
- }
144
-
145
- .btn-primary {
146
- background: var(--primary-color-ml);
147
- color: #ffffff;
148
- border-color: var(--primary-color-ml);
149
- box-shadow: 0 2px 4px rgba(15, 118, 110, 0.2);
150
- }
151
-
152
- .btn-primary:hover {
153
- background: var(--primary-dark-color-ml);
154
- border-color: var(--primary-dark-color-ml);
155
- color: #ffffff;
156
- transform: translateY(-1px);
157
- }
158
-
159
- .btn-outline {
160
- background: rgba(255, 255, 255, 0.9);
161
- color: var(--dark-color-ml);
162
- border-color: var(--border-color);
163
- }
164
-
165
- .btn-outline:hover {
166
- background: var(--primary-light-color-ml);
167
- color: var(--primary-dark-color-ml);
168
- border-color: var(--primary-color-ml);
169
- }
170
-
171
- .btn-danger {
172
- background: var(--danger-color-ml);
173
- color: #ffffff;
174
- border-color: var(--danger-color-ml);
175
- }
176
-
177
- .btn-danger:hover {
178
- background: #b91c1c;
179
- border-color: #b91c1c;
180
- color: #ffffff;
181
- }
182
-
183
- .btn-sm {
184
- padding: 5px 11px;
185
- font-size: 12px;
186
- }
187
-
188
- .btn-icon {
189
- width: 32px;
190
- height: 32px;
191
- padding: 0;
192
- display: inline-flex;
193
- align-items: center;
194
- justify-content: center;
195
- }
196
-
197
- /* File Manager Card Layout */
198
- .card.file-manager {
199
- background: rgba(255, 255, 255, 0.85);
200
- backdrop-filter: blur(14px);
201
- border: 1px solid rgba(255, 255, 255, 0.9);
202
- border-radius: var(--radius-lg);
203
- box-shadow: 0 14px 38px rgba(15, 23, 42, 0.06);
204
- overflow: hidden;
205
- }
206
-
207
- .fm-layout {
208
- display: grid;
209
- grid-template-columns: 260px minmax(0, 1fr);
210
- height: calc(100vh - 180px);
211
- min-height: 580px;
212
- max-height: 900px;
213
- }
214
-
215
- /* Left Sidebar Tree */
216
- .fm-tree-wrap {
217
- border-right: 1px solid var(--border-color);
218
- background: rgba(244, 247, 243, 0.65);
219
- display: flex;
220
- flex-direction: column;
221
- padding: 12px 10px;
222
- min-height: 0;
223
- }
224
-
225
- .fm-tree-header {
226
- padding: 4px 10px 8px;
227
- display: flex;
228
- align-items: center;
229
- justify-content: space-between;
230
- }
231
-
232
- .fm-tree-title {
233
- font-family: var(--font-headings);
234
- font-size: 11px;
235
- font-weight: 700;
236
- text-transform: uppercase;
237
- letter-spacing: 0.6px;
238
- color: var(--primary-dark-color-ml);
239
- }
240
-
241
- .fm-tree {
242
- flex: 1 1 auto;
243
- overflow-y: auto;
244
- padding-right: 4px;
245
- }
246
-
247
- .fm-tree::-webkit-scrollbar {
248
- width: 5px;
249
- }
250
- .fm-tree::-webkit-scrollbar-thumb {
251
- background: var(--gray-light-color-ml);
252
- border-radius: 3px;
253
- }
254
-
255
- .tree-group {
256
- margin-bottom: 3px;
257
- }
258
-
259
- .tree-link {
260
- display: flex;
261
- align-items: center;
262
- gap: 8px;
263
- width: 100%;
264
- padding: 7px 11px;
265
- background: transparent;
266
- border: none;
267
- border-radius: var(--radius-sm);
268
- font-family: var(--font);
269
- font-size: 13px;
270
- color: var(--text-secondary);
271
- text-align: left;
272
- cursor: pointer;
273
- transition: all 0.12s ease;
274
- user-select: none;
275
- font-weight: 500;
276
- }
277
-
278
- .tree-link:hover {
279
- background: rgba(255, 255, 255, 0.8);
280
- color: var(--primary-dark-color-ml);
281
- }
282
-
283
- .tree-link.active {
284
- background: var(--primary-light-color-ml);
285
- color: var(--primary-dark-color-ml);
286
- font-weight: 600;
287
- }
288
-
289
- .tree-link svg {
290
- color: var(--gray-color-ml);
291
- flex-shrink: 0;
292
- }
293
-
294
- .tree-link.active svg {
295
- color: var(--primary-color-ml);
296
- }
297
-
298
- .tree-link span {
299
- flex: 1 1 auto;
300
- min-width: 0;
301
- overflow: hidden;
302
- text-overflow: ellipsis;
303
- white-space: nowrap;
304
- color: inherit;
305
- font-size: 13px;
306
- }
307
-
308
- .tree-subs {
309
- display: flex;
310
- flex-direction: column;
311
- margin-left: 12px;
312
- padding-left: 6px;
313
- border-left: 1px solid var(--border-color);
314
- }
315
-
316
- .tree-sub {
317
- padding-left: 12px;
318
- }
319
-
320
- .tree-badge {
321
- font-size: 10.5px;
322
- padding: 1px 7px;
323
- border-radius: 99px;
324
- background: var(--primary-light-color-ml);
325
- color: var(--primary-dark-color-ml);
326
- font-weight: 600;
327
- }
328
-
329
- /* Sidebar Storage & Bucket Section */
330
- .fm-storage {
331
- margin-top: auto;
332
- padding: 12px;
333
- border-top: 1px solid var(--border-color);
334
- background: rgba(255, 255, 255, 0.85);
335
- border-radius: var(--radius);
336
- box-shadow: 0 2px 8px rgba(15, 118, 110, 0.05);
337
- }
338
-
339
- .fm-storage-label {
340
- font-size: 10.5px;
341
- font-weight: 700;
342
- text-transform: uppercase;
343
- letter-spacing: 0.5px;
344
- color: var(--primary-dark-color-ml);
345
- margin-bottom: 6px;
346
- }
347
-
348
- .bucket-switcher-wrap {
349
- position: relative;
350
- }
351
-
352
- .bucket-switcher-control {
353
- position: relative;
354
- display: flex;
355
- align-items: center;
356
- }
357
-
358
- .bucket-switcher-icon {
359
- position: absolute;
360
- left: 10px;
361
- color: var(--primary-color-ml);
362
- pointer-events: none;
363
- }
364
-
365
- .bucket-switcher-select {
366
- width: 100%;
367
- padding: 6px 10px 6px 30px;
368
- font-family: var(--font);
369
- font-size: 12.5px;
370
- font-weight: 600;
371
- color: var(--dark-color-ml);
372
- background: var(--light-color-ml);
373
- border: 1px solid var(--border-color);
374
- border-radius: var(--radius-sm);
375
- outline: none;
376
- cursor: pointer;
377
- appearance: auto;
378
- transition: border-color 0.15s ease;
379
- }
380
-
381
- .bucket-switcher-select:focus {
382
- border-color: var(--primary-color-ml);
383
- }
384
-
385
- .bucket-switcher-status {
386
- font-size: 11px;
387
- color: var(--primary-color-ml);
388
- margin-top: 4px;
389
- display: block;
390
- }
391
-
392
- .storage-bar {
393
- height: 5px;
394
- background: var(--gray-light-color-ml);
395
- border-radius: 3px;
396
- overflow: hidden;
397
- margin: 8px 0 6px;
398
- }
399
-
400
- .fm-storage-meta {
401
- font-size: 11.5px;
402
- color: var(--gray-color-ml);
403
- font-weight: 600;
404
- }
405
-
406
- .fm-storage-subinfo {
407
- font-size: 10.5px;
408
- color: var(--gray-color-ml);
409
- margin-top: 2px;
410
- white-space: nowrap;
411
- overflow: hidden;
412
- text-overflow: ellipsis;
413
- }
414
-
415
- /* Main Content Area */
416
- .fm-main {
417
- display: flex;
418
- flex-direction: column;
419
- min-height: 0;
420
- background: rgba(255, 255, 255, 0.9);
421
- }
422
-
423
- /* Toolbar */
424
- .fm-toolbar {
425
- display: flex;
426
- align-items: center;
427
- justify-content: space-between;
428
- gap: 12px;
429
- padding: 10px 16px;
430
- border-bottom: 1px solid var(--border-color);
431
- flex-shrink: 0;
432
- background: rgba(255, 255, 255, 0.7);
433
- flex-wrap: wrap;
434
- }
435
-
436
- .fm-breadcrumb {
437
- display: flex;
438
- align-items: center;
439
- gap: 5px;
440
- flex-wrap: wrap;
441
- min-height: 32px;
442
- }
443
-
444
- .bc-link {
445
- background: transparent;
446
- border: none;
447
- font-family: var(--font);
448
- font-size: 13px;
449
- color: var(--gray-color-ml);
450
- cursor: pointer;
451
- padding: 3px 8px;
452
- border-radius: var(--radius-sm);
453
- transition: all 0.12s ease;
454
- display: inline-flex;
455
- align-items: center;
456
- gap: 4px;
457
- font-weight: 500;
458
- }
459
-
460
- .bc-link:hover {
461
- background: var(--primary-light-color-ml);
462
- color: var(--primary-dark-color-ml);
463
- }
464
-
465
- .bc-link.current {
466
- color: var(--dark-color-ml);
467
- font-weight: 700;
468
- cursor: default;
469
- }
470
-
471
- .bc-link.current:hover {
472
- background: transparent;
473
- }
474
-
475
- .fm-breadcrumb .sep {
476
- color: var(--gray-color-ml);
477
- font-size: 13px;
478
- user-select: none;
479
- }
480
-
481
- .fm-toolbar-actions {
482
- display: flex;
483
- align-items: center;
484
- gap: 10px;
485
- margin-left: auto;
486
- }
487
-
488
- /* Quick Filters */
489
- .quick-filter-group {
490
- display: inline-flex;
491
- background: rgba(15, 118, 110, 0.06);
492
- border: 1px solid var(--border-color);
493
- border-radius: var(--radius);
494
- padding: 2px;
495
- }
496
-
497
- .quick-filter-btn {
498
- background: transparent;
499
- border: none;
500
- font-family: var(--font);
501
- font-size: 12px;
502
- font-weight: 600;
503
- color: var(--text-secondary);
504
- padding: 4px 11px;
505
- border-radius: var(--radius-sm);
506
- cursor: pointer;
507
- transition: all 0.12s ease;
508
- }
509
-
510
- .quick-filter-btn:hover {
511
- color: var(--primary-dark-color-ml);
512
- }
513
-
514
- .quick-filter-btn.active {
515
- background: #ffffff;
516
- color: var(--primary-color-ml);
517
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
518
- }
519
-
520
- /* Search Box */
521
- .search-box {
522
- position: relative;
523
- width: 210px;
524
- display: flex;
525
- align-items: center;
526
- }
527
-
528
- .search-box .s-icon {
529
- position: absolute;
530
- left: 9px;
531
- width: 14px;
532
- height: 14px;
533
- color: var(--gray-color-ml);
534
- pointer-events: none;
535
- }
536
-
537
- .search-box input {
538
- width: 100%;
539
- padding: 6px 26px 6px 28px;
540
- font-family: var(--font);
541
- font-size: 12.5px;
542
- border: 1px solid var(--border-color);
543
- border-radius: var(--radius);
544
- background: rgba(255, 255, 255, 0.85);
545
- color: var(--dark-color-ml);
546
- outline: none;
547
- transition: all 0.15s ease;
548
- }
549
-
550
- .search-box input:focus {
551
- border-color: var(--primary-color-ml);
552
- background: #ffffff;
553
- box-shadow: 0 0 0 3px var(--primary-light-color-ml);
554
- }
555
-
556
- .search-clear-btn {
557
- position: absolute;
558
- right: 6px;
559
- background: transparent;
560
- border: none;
561
- color: var(--gray-color-ml);
562
- cursor: pointer;
563
- font-size: 16px;
564
- line-height: 1;
565
- padding: 2px 4px;
566
- }
567
-
568
- /* View Switcher */
569
- .fm-view-toggle {
570
- display: inline-flex;
571
- border: 1px solid var(--border-color);
572
- border-radius: var(--radius);
573
- overflow: hidden;
574
- background: #ffffff;
575
- }
576
-
577
- .view-btn {
578
- width: 32px;
579
- height: 30px;
580
- border: none;
581
- background: transparent;
582
- cursor: pointer;
583
- color: var(--gray-color-ml);
584
- display: flex;
585
- align-items: center;
586
- justify-content: center;
587
- transition: all 0.12s ease;
588
- }
589
-
590
- .view-btn:hover {
591
- background: var(--light-color-ml);
592
- color: var(--dark-color-ml);
593
- }
594
-
595
- .view-btn.active {
596
- background: var(--primary-light-color-ml);
597
- color: var(--primary-dark-color-ml);
598
- }
599
-
600
- /* File Grid Wrap & Items */
601
- .fm-grid-wrap {
602
- flex: 1 1 auto;
603
- overflow-y: auto;
604
- padding: 16px;
605
- position: relative;
606
- }
607
-
608
- .fm-grid-wrap::-webkit-scrollbar {
609
- width: 6px;
610
- }
611
- .fm-grid-wrap::-webkit-scrollbar-thumb {
612
- background: var(--gray-light-color-ml);
613
- border-radius: 3px;
614
- }
615
-
616
- /* Grid View */
617
- .fm-grid.view-grid {
618
- display: grid;
619
- grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
620
- grid-auto-rows: max-content;
621
- align-content: start;
622
- gap: 14px;
623
- }
624
-
625
- .fm-item {
626
- position: relative;
627
- background: rgba(255, 255, 255, 0.95);
628
- border: 1px solid rgba(15, 118, 110, 0.15);
629
- border-radius: var(--radius-lg);
630
- cursor: pointer;
631
- font-family: var(--font);
632
- text-align: left;
633
- transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
634
- user-select: none;
635
- }
636
-
637
- .fm-item:hover {
638
- border-color: var(--primary-color-ml);
639
- transform: translateY(-2px);
640
- box-shadow: 0 8px 20px rgba(15, 118, 110, 0.1);
641
- }
642
-
643
- .fm-item.is-selected {
644
- border-color: var(--primary-color-ml);
645
- background: var(--primary-light-color-ml);
646
- }
647
-
648
- /* Item styling in Grid View */
649
- .fm-grid.view-grid .fm-item {
650
- padding: 12px;
651
- display: flex;
652
- flex-direction: column;
653
- align-items: flex-start;
654
- gap: 8px;
655
- }
656
-
657
- .fm-grid.view-grid .fm-item-icon {
658
- width: 100%;
659
- aspect-ratio: 16 / 10;
660
- border-radius: var(--radius);
661
- display: flex;
662
- align-items: center;
663
- justify-content: center;
664
- flex-shrink: 0;
665
- background: var(--light-color-ml);
666
- overflow: hidden;
667
- position: relative;
668
- }
669
-
670
- .fm-item-thumb {
671
- width: 100%;
672
- height: 100%;
673
- object-fit: cover;
674
- }
675
-
676
- .fm-item-icon .ext {
677
- font-size: 13px;
678
- font-weight: 700;
679
- letter-spacing: 0.6px;
680
- text-transform: uppercase;
681
- }
682
-
683
- .fm-item-icon .folder-svg {
684
- width: 42px;
685
- height: 42px;
686
- }
687
-
688
- .fm-grid.view-grid .fm-item-details {
689
- width: 100%;
690
- min-width: 0;
691
- }
692
-
693
- .fm-item-name {
694
- font-size: 13px;
695
- font-weight: 600;
696
- color: var(--dark-color-ml);
697
- overflow: hidden;
698
- text-overflow: ellipsis;
699
- white-space: nowrap;
700
- min-width: 0;
701
- }
702
-
703
- .fm-item-meta {
704
- font-size: 11.5px;
705
- color: var(--gray-color-ml);
706
- margin-top: 2px;
707
- white-space: nowrap;
708
- overflow: hidden;
709
- text-overflow: ellipsis;
710
- }
711
-
712
- /* Star & Context Menu Buttons */
713
- .fm-star {
714
- position: absolute;
715
- top: 8px;
716
- left: 8px;
717
- width: 24px;
718
- height: 24px;
719
- display: flex;
720
- align-items: center;
721
- justify-content: center;
722
- cursor: pointer;
723
- border-radius: 50%;
724
- color: var(--text-disabled);
725
- opacity: 0;
726
- background: rgba(255, 255, 255, 0.9);
727
- backdrop-filter: blur(4px);
728
- transition: opacity 0.12s ease, color 0.12s ease;
729
- z-index: 2;
730
- border: none;
731
- }
732
-
733
- .fm-item:hover .fm-star,
734
- .fm-item.starred .fm-star {
735
- opacity: 1;
736
- }
737
-
738
- .fm-star.on {
739
- color: var(--yellow);
740
- opacity: 1;
741
- }
742
-
743
- .fm-star:hover {
744
- color: var(--yellow);
745
- transform: scale(1.1);
746
- }
747
-
748
- .fm-item-menu {
749
- position: absolute;
750
- top: 8px;
751
- right: 8px;
752
- width: 24px;
753
- height: 24px;
754
- border: none;
755
- background: rgba(255, 255, 255, 0.9);
756
- backdrop-filter: blur(4px);
757
- border-radius: 50%;
758
- display: flex;
759
- align-items: center;
760
- justify-content: center;
761
- cursor: pointer;
762
- color: var(--gray-color-ml);
763
- opacity: 0;
764
- transition: opacity 0.12s ease, background 0.12s ease, color 0.12s ease;
765
- z-index: 2;
766
- }
767
-
768
- .fm-item:hover .fm-item-menu {
769
- opacity: 1;
770
- }
771
-
772
- .fm-item-menu:hover {
773
- background: #ffffff;
774
- color: var(--primary-dark-color-ml);
775
- box-shadow: var(--shadow-sm);
776
- }
777
-
778
- /* List View */
779
- .fm-grid.view-list {
780
- display: flex;
781
- flex-direction: column;
782
- gap: 4px;
783
- }
784
-
785
- .fm-grid.view-list .fm-item {
786
- padding: 8px 14px;
787
- display: grid;
788
- grid-template-columns: 20px 32px 1fr 110px 140px 32px 32px;
789
- gap: 12px;
790
- align-items: center;
791
- border-radius: var(--radius);
792
- }
793
-
794
- .fm-grid.view-list .fm-item-icon {
795
- width: 32px;
796
- height: 32px;
797
- border-radius: var(--radius-sm);
798
- display: flex;
799
- align-items: center;
800
- justify-content: center;
801
- background: var(--light-color-ml);
802
- }
803
-
804
- .fm-grid.view-list .fm-item-icon .ext {
805
- font-size: 10.5px;
806
- font-weight: 700;
807
- }
808
-
809
- .fm-grid.view-list .fm-item-icon .folder-svg {
810
- width: 22px;
811
- height: 22px;
812
- }
813
-
814
- .fm-grid.view-list .fm-star,
815
- .fm-grid.view-list .fm-item-menu {
816
- position: static;
817
- opacity: 1;
818
- background: transparent;
819
- }
820
-
821
- .fm-grid.view-list .fm-item-meta {
822
- font-size: 12px;
823
- margin-top: 0;
824
- }
825
-
826
- /* Header row for list view */
827
- .fm-list-header {
828
- display: grid;
829
- grid-template-columns: 20px 32px 1fr 110px 140px 32px 32px;
830
- gap: 12px;
831
- align-items: center;
832
- padding: 6px 14px;
833
- font-size: 11px;
834
- font-weight: 700;
835
- text-transform: uppercase;
836
- letter-spacing: 0.5px;
837
- color: var(--primary-dark-color-ml);
838
- border-bottom: 1px solid var(--border-color);
839
- margin-bottom: 4px;
840
- }
841
-
842
- /* Empty State */
843
- .fm-empty {
844
- padding: 80px 20px;
845
- text-align: center;
846
- color: var(--gray-color-ml);
847
- display: flex;
848
- flex-direction: column;
849
- align-items: center;
850
- justify-content: center;
851
- }
852
-
853
- .fm-empty[hidden],
854
- [hidden] {
855
- display: none !important;
856
- }
857
-
858
- .fm-empty svg {
859
- color: var(--text-disabled);
860
- margin-bottom: 12px;
861
- }
862
-
863
- .fm-empty .empty-title {
864
- font-family: var(--font-headings);
865
- font-size: 15px;
866
- font-weight: 700;
867
- color: var(--dark-color-ml);
868
- margin-bottom: 4px;
869
- }
870
-
871
- .fm-empty .empty-desc {
872
- font-size: 13px;
873
- max-width: 360px;
874
- }
875
-
876
- /* Skeletons */
877
- .fm-skeleton-grid {
878
- display: grid;
879
- grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
880
- gap: 14px;
881
- width: 100%;
882
- }
883
-
884
- .fm-skeleton-card {
885
- background: rgba(255, 255, 255, 0.8);
886
- border: 1px solid var(--border-color-light);
887
- border-radius: var(--radius-lg);
888
- padding: 12px;
889
- display: flex;
890
- flex-direction: column;
891
- gap: 8px;
892
- }
893
-
894
- .fm-skeleton-icon {
895
- width: 100%;
896
- aspect-ratio: 16 / 10;
897
- border-radius: var(--radius);
898
- background: linear-gradient(90deg, #eaf2ee 25%, #dce8e3 50%, #eaf2ee 75%);
899
- background-size: 200% 100%;
900
- animation: fm-shimmer 1.5s infinite;
901
- }
902
-
903
- .fm-skeleton-line {
904
- height: 12px;
905
- border-radius: 4px;
906
- background: linear-gradient(90deg, #eaf2ee 25%, #dce8e3 50%, #eaf2ee 75%);
907
- background-size: 200% 100%;
908
- animation: fm-shimmer 1.5s infinite;
909
- }
910
-
911
- .fm-skeleton-line.w-75 { width: 75%; }
912
- .fm-skeleton-line.w-50 { width: 50%; }
913
-
914
- @keyframes fm-shimmer {
915
- 0% { background-position: 200% 0; }
916
- 100% { background-position: -200% 0; }
917
- }
918
-
919
- /* Context Menu */
920
- .fm-context-menu {
921
- position: fixed;
922
- z-index: 1000;
923
- background: rgba(255, 255, 255, 0.95);
924
- backdrop-filter: blur(12px);
925
- border: 1px solid var(--border-color);
926
- border-radius: var(--radius-lg);
927
- box-shadow: var(--shadow-dropdown);
928
- padding: 6px;
929
- min-width: 175px;
930
- animation: fm-menu-pop 0.12s cubic-bezier(0.16, 1, 0.3, 1);
931
- }
932
-
933
- @keyframes fm-menu-pop {
934
- from { opacity: 0; transform: scale(0.95); }
935
- to { opacity: 1; transform: scale(1); }
936
- }
937
-
938
- .fm-context-item {
939
- display: flex;
940
- align-items: center;
941
- gap: 8px;
942
- width: 100%;
943
- padding: 7px 11px;
944
- border: none;
945
- background: transparent;
946
- font-family: var(--font);
947
- font-size: 12.5px;
948
- font-weight: 500;
949
- color: var(--dark-color-ml);
950
- border-radius: var(--radius-sm);
951
- cursor: pointer;
952
- text-align: left;
953
- transition: background 0.1s ease, color 0.1s ease;
954
- }
955
-
956
- .fm-context-item:hover {
957
- background: var(--primary-light-color-ml);
958
- color: var(--primary-dark-color-ml);
959
- }
960
-
961
- .fm-context-item.danger:hover {
962
- background: var(--red-lt);
963
- color: var(--danger-color-ml);
964
- }
965
-
966
- .fm-context-divider {
967
- height: 1px;
968
- background: var(--border-color-light);
969
- margin: 4px 0;
970
- }
971
-
972
- /* Modals */
973
- .modal {
974
- display: none;
975
- position: fixed;
976
- inset: 0;
977
- z-index: 1050;
978
- overflow-x: hidden;
979
- overflow-y: auto;
980
- background: rgba(15, 42, 42, 0.45);
981
- backdrop-filter: blur(6px);
982
- align-items: center;
983
- justify-content: center;
984
- padding: 1rem;
985
- }
986
-
987
- .modal.show {
988
- display: flex;
989
- }
990
-
991
- .modal-dialog {
992
- position: relative;
993
- width: 100%;
994
- max-width: 480px;
995
- margin: auto;
996
- animation: modal-enter 0.2s cubic-bezier(0.16, 1, 0.3, 1);
997
- }
998
-
999
- .modal-dialog.modal-lg {
1000
- max-width: 680px;
1001
- }
1002
-
1003
- .modal-dialog.preview-modal-dialog {
1004
- max-width: 900px;
1005
- }
1006
-
1007
- .preview-modal-dialog.is-fullscreen {
1008
- max-width: 98vw;
1009
- height: 96vh;
1010
- }
1011
-
1012
- .preview-modal-dialog.is-fullscreen .modal-content {
1013
- height: 100%;
1014
- }
1015
-
1016
- .preview-modal-dialog.is-fullscreen .preview-content {
1017
- max-height: calc(96vh - 120px);
1018
- }
1019
-
1020
- @keyframes modal-enter {
1021
- from { opacity: 0; transform: translateY(-12px) scale(0.98); }
1022
- to { opacity: 1; transform: translateY(0) scale(1); }
1023
- }
1024
-
1025
- .modal-content {
1026
- position: relative;
1027
- display: flex;
1028
- flex-direction: column;
1029
- width: 100%;
1030
- background: #ffffff;
1031
- border: 1px solid var(--border-color);
1032
- border-radius: var(--radius-xl);
1033
- box-shadow: 0 20px 40px rgba(15, 42, 42, 0.16);
1034
- outline: 0;
1035
- }
1036
-
1037
- .modal-header {
1038
- display: flex;
1039
- align-items: center;
1040
- justify-content: space-between;
1041
- padding: 14px 18px;
1042
- border-bottom: 1px solid var(--border-color);
1043
- }
1044
-
1045
- .modal-title {
1046
- font-family: var(--font-headings);
1047
- display: flex;
1048
- align-items: center;
1049
- gap: 8px;
1050
- font-size: 15px;
1051
- font-weight: 700;
1052
- color: var(--primary-dark-color-ml);
1053
- margin: 0;
1054
- }
1055
-
1056
- .modal-title-icon {
1057
- color: var(--primary-color-ml);
1058
- }
1059
-
1060
- .btn-close {
1061
- background: transparent;
1062
- border: none;
1063
- font-size: 20px;
1064
- line-height: 1;
1065
- color: var(--gray-color-ml);
1066
- cursor: pointer;
1067
- padding: 4px;
1068
- border-radius: var(--radius-sm);
1069
- transition: all 0.12s ease;
1070
- }
1071
-
1072
- .btn-close:hover {
1073
- color: var(--dark-color-ml);
1074
- background: var(--light-color-ml);
1075
- }
1076
-
1077
- .modal-body {
1078
- position: relative;
1079
- flex: 1 1 auto;
1080
- padding: 18px;
1081
- }
1082
-
1083
- .modal-footer {
1084
- display: flex;
1085
- align-items: center;
1086
- justify-content: flex-end;
1087
- gap: 8px;
1088
- padding: 12px 18px;
1089
- border-top: 1px solid var(--border-color);
1090
- background: var(--light-color-ml);
1091
- border-bottom-left-radius: var(--radius-xl);
1092
- border-bottom-right-radius: var(--radius-xl);
1093
- }
1094
-
1095
- /* Upload Dropzone & Queue */
1096
- .upload-drop-zone {
1097
- border: 2px dashed var(--primary-color-ml);
1098
- border-radius: var(--radius-lg);
1099
- padding: 32px 20px;
1100
- text-align: center;
1101
- background: var(--primary-light-color-ml);
1102
- cursor: pointer;
1103
- transition: all 0.15s ease;
1104
- }
1105
-
1106
- .upload-drop-zone:hover,
1107
- .upload-drop-zone.dragover {
1108
- border-color: var(--primary-dark-color-ml);
1109
- background: #c5efe7;
1110
- }
1111
-
1112
- .drop-icon {
1113
- color: var(--primary-color-ml);
1114
- margin-bottom: 10px;
1115
- }
1116
-
1117
- .drop-text {
1118
- font-size: 14px;
1119
- font-weight: 600;
1120
- color: var(--dark-color-ml);
1121
- }
1122
-
1123
- .drop-browse-link {
1124
- color: var(--primary-color-ml);
1125
- text-decoration: underline;
1126
- cursor: pointer;
1127
- }
1128
-
1129
- .drop-hint {
1130
- font-size: 12px;
1131
- color: var(--gray-color-ml);
1132
- margin-top: 4px;
1133
- }
1134
-
1135
- .upload-queue {
1136
- max-height: 200px;
1137
- overflow-y: auto;
1138
- display: flex;
1139
- flex-direction: column;
1140
- gap: 6px;
1141
- }
1142
-
1143
- .upload-queue-item {
1144
- display: flex;
1145
- align-items: center;
1146
- justify-content: space-between;
1147
- padding: 8px 12px;
1148
- background: var(--light-color-ml);
1149
- border: 1px solid var(--border-color);
1150
- border-radius: var(--radius);
1151
- font-size: 12.5px;
1152
- }
1153
-
1154
- .upload-queue-meta {
1155
- color: var(--gray-color-ml);
1156
- font-size: 11.5px;
1157
- }
1158
-
1159
- .progress-bar-wrap {
1160
- height: 6px;
1161
- background: var(--gray-light-color-ml);
1162
- border-radius: 3px;
1163
- overflow: hidden;
1164
- }
1165
-
1166
- .progress-bar-inner {
1167
- height: 100%;
1168
- background: var(--primary-color-ml);
1169
- transition: width 0.2s ease;
1170
- }
1171
-
1172
- .upload-percent {
1173
- font-size: 12px;
1174
- font-weight: 700;
1175
- color: var(--primary-color-ml);
1176
- }
1177
-
1178
- /* Modal Form Inputs */
1179
- .form-label {
1180
- font-size: 12.5px;
1181
- font-weight: 600;
1182
- color: var(--dark-color-ml);
1183
- margin-bottom: 6px;
1184
- display: block;
1185
- }
1186
-
1187
- .form-control {
1188
- width: 100%;
1189
- padding: 8px 12px;
1190
- font-family: var(--font);
1191
- font-size: 13px;
1192
- color: var(--dark-color-ml);
1193
- background: #ffffff;
1194
- border: 1px solid var(--border-color);
1195
- border-radius: var(--radius);
1196
- outline: none;
1197
- transition: border-color 0.15s ease, box-shadow 0.15s ease;
1198
- }
1199
-
1200
- .form-control:focus {
1201
- border-color: var(--primary-color-ml);
1202
- box-shadow: 0 0 0 3px var(--primary-light-color-ml);
1203
- }
1204
-
1205
- .form-text {
1206
- font-size: 11.5px;
1207
- color: var(--gray-color-ml);
1208
- margin-top: 4px;
1209
- }
1210
-
1211
- /* Preview Modal Content */
1212
- .preview-content {
1213
- max-height: 70vh;
1214
- overflow: auto;
1215
- display: flex;
1216
- align-items: center;
1217
- justify-content: center;
1218
- background: #152222;
1219
- min-height: 280px;
1220
- }
1221
-
1222
- .preview-content img {
1223
- max-width: 100%;
1224
- max-height: 70vh;
1225
- object-fit: contain;
1226
- }
1227
-
1228
- .preview-content video,
1229
- .preview-content audio {
1230
- max-width: 100%;
1231
- max-height: 70vh;
1232
- }
1233
-
1234
- .preview-code-block {
1235
- width: 100%;
1236
- height: 100%;
1237
- max-height: 70vh;
1238
- margin: 0;
1239
- padding: 16px;
1240
- background: #1a2828;
1241
- color: #f4f7f3;
1242
- font-family: var(--font-mono);
1243
- font-size: 12.5px;
1244
- overflow: auto;
1245
- line-height: 1.5;
1246
- }
1247
-
1248
- .preview-iframe {
1249
- width: 100%;
1250
- height: 70vh;
1251
- border: none;
1252
- }
1253
-
1254
- .preview-actions {
1255
- display: flex;
1256
- align-items: center;
1257
- gap: 8px;
1258
- }
1259
-
1260
- /* Toast Container & Notifications */
1261
- .toast-container {
1262
- position: fixed;
1263
- bottom: 20px;
1264
- right: 20px;
1265
- z-index: 1100;
1266
- display: flex;
1267
- flex-direction: column;
1268
- gap: 8px;
1269
- pointer-events: none;
1270
- }
1271
-
1272
- .toast-notification {
1273
- pointer-events: auto;
1274
- display: flex;
1275
- align-items: center;
1276
- gap: 10px;
1277
- padding: 10px 16px;
1278
- border-radius: var(--radius);
1279
- background: var(--dark-color-ml);
1280
- color: #ffffff;
1281
- font-family: var(--font);
1282
- font-size: 13px;
1283
- font-weight: 500;
1284
- box-shadow: var(--shadow-lg);
1285
- min-width: 260px;
1286
- max-width: 400px;
1287
- transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.25s ease;
1288
- }
1289
-
1290
- .toast-notification.success {
1291
- background: linear-gradient(135deg, #10b981, #059669);
1292
- }
1293
-
1294
- .toast-notification.error {
1295
- background: linear-gradient(135deg, #ef4444, #dc2626);
1296
- }
1297
-
1298
- .toast-notification.warning {
1299
- background: linear-gradient(135deg, #f59e0b, #d97706);
1300
- }
1301
-
1302
- .toast-close-btn {
1303
- margin-left: auto;
1304
- background: transparent;
1305
- border: none;
1306
- color: rgba(255, 255, 255, 0.85);
1307
- cursor: pointer;
1308
- font-size: 16px;
1309
- line-height: 1;
1310
- }
1311
-
1312
- /* Pagination */
1313
- .pagination-container {
1314
- padding: 12px 16px;
1315
- border-top: 1px solid var(--border-color);
1316
- display: flex;
1317
- align-items: center;
1318
- justify-content: flex-end;
1319
- }
1320
-
1321
- .pagination {
1322
- display: flex;
1323
- align-items: center;
1324
- gap: 4px;
1325
- list-style: none;
1326
- margin: 0;
1327
- padding: 0;
1328
- }
1329
-
1330
- .page-item .page-link {
1331
- display: flex;
1332
- align-items: center;
1333
- justify-content: center;
1334
- min-width: 28px;
1335
- height: 28px;
1336
- padding: 0 6px;
1337
- border-radius: var(--radius-sm);
1338
- border: 1px solid var(--border-color);
1339
- background: #ffffff;
1340
- color: var(--text-secondary);
1341
- font-size: 12px;
1342
- font-weight: 600;
1343
- text-decoration: none;
1344
- cursor: pointer;
1345
- transition: all 0.12s ease;
1346
- }
1347
-
1348
- .page-item .page-link:hover {
1349
- background: var(--primary-light-color-ml);
1350
- color: var(--primary-dark-color-ml);
1351
- }
1352
-
1353
- .page-item.active .page-link {
1354
- background: var(--primary-color-ml);
1355
- border-color: var(--primary-color-ml);
1356
- color: #ffffff;
1357
- }
1358
-
1359
- .page-item.disabled .page-link {
1360
- opacity: 0.4;
1361
- cursor: not-allowed;
1362
- }
1363
-
1364
- /* Mobile & Tablet Responsiveness */
1365
- @media (max-width: 900px) {
1366
- .fm-layout {
1367
- grid-template-columns: 1fr;
1368
- height: auto;
1369
- max-height: none;
1370
- }
1371
-
1372
- .fm-tree-wrap {
1373
- display: none;
1374
- }
1375
-
1376
- .fm-grid-wrap {
1377
- min-height: 400px;
1378
- }
1379
- }
1380
-
1381
- @media (max-width: 640px) {
1382
- .page-header-row {
1383
- flex-direction: column;
1384
- align-items: flex-start;
1385
- }
1386
-
1387
- .page-actions {
1388
- width: 100%;
1389
- justify-content: flex-start;
1390
- }
1391
-
1392
- .fm-toolbar {
1393
- flex-direction: column;
1394
- align-items: stretch;
1395
- }
1396
-
1397
- .fm-toolbar-actions {
1398
- width: 100%;
1399
- justify-content: space-between;
1400
- flex-wrap: wrap;
1401
- }
1402
-
1403
- .search-box {
1404
- width: 100%;
1405
- }
1406
-
1407
- .fm-grid.view-list .fm-item {
1408
- grid-template-columns: 32px 1fr 32px;
1409
- }
1410
-
1411
- .fm-grid.view-list .fm-item-size,
1412
- .fm-grid.view-list .fm-item-date,
1413
- .fm-grid.view-list .fm-item-checkbox {
1414
- display: none;
1415
- }
1416
-
1417
- .fm-list-header {
1418
- display: none;
1419
- }
1420
- }
1
+ /* ==========================================================================
2
+ MBKBucket File Manager - Original Theme Palette + Gentelella v4 Layout
3
+ ========================================================================== */
4
+
5
+ :root {
6
+ --primary-color-ml: #0f766e;
7
+ --primary-light-color-ml: #d7f4ee;
8
+ --primary-dark-color-ml: #0b4f4a;
9
+ --secondary-color-ml: #1f8f84;
10
+ --dark-color-ml: #1f2a2a;
11
+ --light-color-ml: #f4f7f3;
12
+ --gray-color-ml: #667c79;
13
+ --gray-light-color-ml: #dce8e3;
14
+ --danger-color-ml: #dc2626;
15
+ --warning-color-ml: #d97706;
16
+ --success-color-ml: #16a34a;
17
+ --info-color-ml: #3b82f6;
18
+
19
+ --primary: var(--primary-color-ml);
20
+ --primary-lt: var(--primary-light-color-ml);
21
+ --primary-dk: var(--primary-dark-color-ml);
22
+ --primary-hover: #0d635c;
23
+
24
+ --body-bg: var(--light-color-ml);
25
+ --bg-surface: rgba(255, 255, 255, 0.82);
26
+ --bg-surface-secondary: rgba(244, 247, 243, 0.85);
27
+ --bg-surface-tertiary: #e2ede8;
28
+
29
+ --border-color: rgba(15, 118, 110, 0.16);
30
+ --border-color-light: rgba(15, 118, 110, 0.08);
31
+
32
+ --text: var(--dark-color-ml);
33
+ --text-secondary: #425855;
34
+ --text-muted: var(--gray-color-ml);
35
+ --text-disabled: #a0b2af;
36
+
37
+ --blue: #066fd1;
38
+ --azure: #1f8f84;
39
+ --green: #16a34a;
40
+ --yellow: #d97706;
41
+ --orange: #ea580c;
42
+ --red: #dc2626;
43
+ --purple: #7c3aed;
44
+ --cyan: #0f766e;
45
+
46
+ --green-lt: rgba(22, 163, 74, 0.12);
47
+ --red-lt: rgba(220, 38, 38, 0.1);
48
+ --yellow-lt: rgba(217, 119, 6, 0.12);
49
+ --blue-lt: rgba(6, 111, 209, 0.1);
50
+ --azure-lt: rgba(31, 143, 132, 0.12);
51
+ --purple-lt: rgba(124, 58, 237, 0.1);
52
+ --cyan-lt: rgba(15, 118, 110, 0.12);
53
+
54
+ --radius-sm: 6px;
55
+ --radius: 8px;
56
+ --radius-lg: 14px;
57
+ --radius-xl: 18px;
58
+
59
+ --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.04);
60
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
61
+ --shadow-md: 0 10px 15px -3px rgba(15, 118, 110, 0.08), 0 4px 6px -2px rgba(0, 0, 0, 0.04);
62
+ --shadow-lg: 0 20px 25px -5px rgba(15, 118, 110, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
63
+ --shadow-dropdown: 0 12px 30px rgba(15, 42, 42, 0.14), 0 4px 10px rgba(0, 0, 0, 0.05);
64
+
65
+ --font: "IBM Plex Sans", "Segoe UI", sans-serif;
66
+ --font-headings: "Sora", "Segoe UI", sans-serif;
67
+ --font-mono: 'JetBrains Mono', 'SF Mono', Consolas, monospace;
68
+ }
69
+
70
+ /* Base Layout & Page Header */
71
+ .page-wrapper {
72
+ max-width: 1600px;
73
+ margin: 0 auto;
74
+ width: 100%;
75
+ }
76
+
77
+ .page-header {
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: space-between;
81
+ margin-bottom: 1.2rem;
82
+ padding: 0.9rem 1.3rem;
83
+ border: 1px solid rgba(255, 255, 255, 0.9);
84
+ border-radius: 1rem;
85
+ background: rgba(255, 255, 255, 0.74);
86
+ backdrop-filter: blur(10px);
87
+ box-shadow: 0 12px 34px rgba(15, 23, 42, 0.05);
88
+ }
89
+
90
+ .page-header-row {
91
+ display: flex;
92
+ align-items: center;
93
+ justify-content: space-between;
94
+ width: 100%;
95
+ gap: 1rem;
96
+ }
97
+
98
+ .page-pretitle {
99
+ font-size: 11px;
100
+ font-weight: 700;
101
+ text-transform: uppercase;
102
+ letter-spacing: 0.6px;
103
+ color: var(--primary-color-ml);
104
+ margin-bottom: 2px;
105
+ }
106
+
107
+ .page-title {
108
+ font-family: var(--font-headings);
109
+ font-size: 1.45rem;
110
+ font-weight: 700;
111
+ color: var(--dark-color-ml);
112
+ margin: 0;
113
+ line-height: 1.2;
114
+ }
115
+
116
+ .page-actions {
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 0.65rem;
120
+ }
121
+
122
+ /* Button System */
123
+ .btn {
124
+ display: inline-flex;
125
+ align-items: center;
126
+ justify-content: center;
127
+ gap: 0.45rem;
128
+ font-family: var(--font);
129
+ font-size: 13px;
130
+ font-weight: 600;
131
+ line-height: 1.4;
132
+ padding: 7px 15px;
133
+ border-radius: var(--radius);
134
+ border: 1px solid transparent;
135
+ cursor: pointer;
136
+ transition: all 0.15s ease-in-out;
137
+ text-decoration: none;
138
+ white-space: nowrap;
139
+ }
140
+
141
+ .btn svg {
142
+ flex-shrink: 0;
143
+ }
144
+
145
+ .btn-primary {
146
+ background: var(--primary-color-ml);
147
+ color: #ffffff;
148
+ border-color: var(--primary-color-ml);
149
+ box-shadow: 0 2px 4px rgba(15, 118, 110, 0.2);
150
+ }
151
+
152
+ .btn-primary:hover {
153
+ background: var(--primary-dark-color-ml);
154
+ border-color: var(--primary-dark-color-ml);
155
+ color: #ffffff;
156
+ transform: translateY(-1px);
157
+ }
158
+
159
+ .btn-outline {
160
+ background: rgba(255, 255, 255, 0.9);
161
+ color: var(--dark-color-ml);
162
+ border-color: var(--border-color);
163
+ }
164
+
165
+ .btn-outline:hover {
166
+ background: var(--primary-light-color-ml);
167
+ color: var(--primary-dark-color-ml);
168
+ border-color: var(--primary-color-ml);
169
+ }
170
+
171
+ .btn-danger {
172
+ background: var(--danger-color-ml);
173
+ color: #ffffff;
174
+ border-color: var(--danger-color-ml);
175
+ }
176
+
177
+ .btn-danger:hover {
178
+ background: #b91c1c;
179
+ border-color: #b91c1c;
180
+ color: #ffffff;
181
+ }
182
+
183
+ .btn-sm {
184
+ padding: 5px 11px;
185
+ font-size: 12px;
186
+ }
187
+
188
+ .btn-icon {
189
+ width: 32px;
190
+ height: 32px;
191
+ padding: 0;
192
+ display: inline-flex;
193
+ align-items: center;
194
+ justify-content: center;
195
+ }
196
+
197
+ /* File Manager Card Layout */
198
+ .card.file-manager {
199
+ background: rgba(255, 255, 255, 0.85);
200
+ backdrop-filter: blur(14px);
201
+ border: 1px solid rgba(255, 255, 255, 0.9);
202
+ border-radius: var(--radius-lg);
203
+ box-shadow: 0 14px 38px rgba(15, 23, 42, 0.06);
204
+ overflow: hidden;
205
+ }
206
+
207
+ .fm-layout {
208
+ display: grid;
209
+ grid-template-columns: 260px minmax(0, 1fr);
210
+ height: calc(100vh - 180px);
211
+ min-height: 580px;
212
+ max-height: 900px;
213
+ }
214
+
215
+ /* Left Sidebar Tree */
216
+ .fm-tree-wrap {
217
+ border-right: 1px solid var(--border-color);
218
+ background: rgba(244, 247, 243, 0.65);
219
+ display: flex;
220
+ flex-direction: column;
221
+ padding: 12px 10px;
222
+ min-height: 0;
223
+ }
224
+
225
+ .fm-tree-header {
226
+ padding: 4px 10px 8px;
227
+ display: flex;
228
+ align-items: center;
229
+ justify-content: space-between;
230
+ }
231
+
232
+ .fm-tree-title {
233
+ font-family: var(--font-headings);
234
+ font-size: 11px;
235
+ font-weight: 700;
236
+ text-transform: uppercase;
237
+ letter-spacing: 0.6px;
238
+ color: var(--primary-dark-color-ml);
239
+ }
240
+
241
+ .fm-tree {
242
+ flex: 1 1 auto;
243
+ overflow-y: auto;
244
+ padding-right: 4px;
245
+ }
246
+
247
+ .fm-tree::-webkit-scrollbar {
248
+ width: 5px;
249
+ }
250
+ .fm-tree::-webkit-scrollbar-thumb {
251
+ background: var(--gray-light-color-ml);
252
+ border-radius: 3px;
253
+ }
254
+
255
+ .tree-group {
256
+ margin-bottom: 3px;
257
+ }
258
+
259
+ .tree-link {
260
+ display: flex;
261
+ align-items: center;
262
+ gap: 8px;
263
+ width: 100%;
264
+ padding: 7px 11px;
265
+ background: transparent;
266
+ border: none;
267
+ border-radius: var(--radius-sm);
268
+ font-family: var(--font);
269
+ font-size: 13px;
270
+ color: var(--text-secondary);
271
+ text-align: left;
272
+ cursor: pointer;
273
+ transition: all 0.12s ease;
274
+ user-select: none;
275
+ font-weight: 500;
276
+ }
277
+
278
+ .tree-link:hover {
279
+ background: rgba(255, 255, 255, 0.8);
280
+ color: var(--primary-dark-color-ml);
281
+ }
282
+
283
+ .tree-link.active {
284
+ background: var(--primary-light-color-ml);
285
+ color: var(--primary-dark-color-ml);
286
+ font-weight: 600;
287
+ }
288
+
289
+ .tree-link svg {
290
+ color: var(--gray-color-ml);
291
+ flex-shrink: 0;
292
+ }
293
+
294
+ .tree-link.active svg {
295
+ color: var(--primary-color-ml);
296
+ }
297
+
298
+ .tree-link span {
299
+ flex: 1 1 auto;
300
+ min-width: 0;
301
+ overflow: hidden;
302
+ text-overflow: ellipsis;
303
+ white-space: nowrap;
304
+ color: inherit;
305
+ font-size: 13px;
306
+ }
307
+
308
+ .tree-subs {
309
+ display: flex;
310
+ flex-direction: column;
311
+ margin-left: 12px;
312
+ padding-left: 6px;
313
+ border-left: 1px solid var(--border-color);
314
+ }
315
+
316
+ .tree-sub {
317
+ padding-left: 12px;
318
+ }
319
+
320
+ .tree-badge {
321
+ font-size: 10.5px;
322
+ padding: 1px 7px;
323
+ border-radius: 99px;
324
+ background: var(--primary-light-color-ml);
325
+ color: var(--primary-dark-color-ml);
326
+ font-weight: 600;
327
+ }
328
+
329
+ /* Sidebar Storage & Bucket Section */
330
+ .fm-storage {
331
+ margin-top: auto;
332
+ padding: 12px;
333
+ border-top: 1px solid var(--border-color);
334
+ background: rgba(255, 255, 255, 0.85);
335
+ border-radius: var(--radius);
336
+ box-shadow: 0 2px 8px rgba(15, 118, 110, 0.05);
337
+ }
338
+
339
+ .fm-storage-label {
340
+ font-size: 10.5px;
341
+ font-weight: 700;
342
+ text-transform: uppercase;
343
+ letter-spacing: 0.5px;
344
+ color: var(--primary-dark-color-ml);
345
+ margin-bottom: 6px;
346
+ }
347
+
348
+ .bucket-switcher-wrap {
349
+ position: relative;
350
+ }
351
+
352
+ .bucket-switcher-control {
353
+ position: relative;
354
+ display: flex;
355
+ align-items: center;
356
+ }
357
+
358
+ .bucket-switcher-icon {
359
+ position: absolute;
360
+ left: 10px;
361
+ color: var(--primary-color-ml);
362
+ pointer-events: none;
363
+ }
364
+
365
+ .bucket-switcher-select {
366
+ width: 100%;
367
+ padding: 6px 10px 6px 30px;
368
+ font-family: var(--font);
369
+ font-size: 12.5px;
370
+ font-weight: 600;
371
+ color: var(--dark-color-ml);
372
+ background: var(--light-color-ml);
373
+ border: 1px solid var(--border-color);
374
+ border-radius: var(--radius-sm);
375
+ outline: none;
376
+ cursor: pointer;
377
+ appearance: auto;
378
+ transition: border-color 0.15s ease;
379
+ }
380
+
381
+ .bucket-switcher-select:focus {
382
+ border-color: var(--primary-color-ml);
383
+ }
384
+
385
+ .bucket-switcher-status {
386
+ font-size: 11px;
387
+ color: var(--primary-color-ml);
388
+ margin-top: 4px;
389
+ display: block;
390
+ }
391
+
392
+ .storage-bar {
393
+ height: 5px;
394
+ background: var(--gray-light-color-ml);
395
+ border-radius: 3px;
396
+ overflow: hidden;
397
+ margin: 8px 0 6px;
398
+ }
399
+
400
+ .fm-storage-meta {
401
+ font-size: 11.5px;
402
+ color: var(--gray-color-ml);
403
+ font-weight: 600;
404
+ }
405
+
406
+ .fm-storage-subinfo {
407
+ font-size: 10.5px;
408
+ color: var(--gray-color-ml);
409
+ margin-top: 2px;
410
+ white-space: nowrap;
411
+ overflow: hidden;
412
+ text-overflow: ellipsis;
413
+ }
414
+
415
+ /* Main Content Area */
416
+ .fm-main {
417
+ display: flex;
418
+ flex-direction: column;
419
+ min-height: 0;
420
+ background: rgba(255, 255, 255, 0.9);
421
+ }
422
+
423
+ /* Toolbar */
424
+ .fm-toolbar {
425
+ display: flex;
426
+ align-items: center;
427
+ justify-content: space-between;
428
+ gap: 12px;
429
+ padding: 10px 16px;
430
+ border-bottom: 1px solid var(--border-color);
431
+ flex-shrink: 0;
432
+ background: rgba(255, 255, 255, 0.7);
433
+ flex-wrap: wrap;
434
+ }
435
+
436
+ .fm-breadcrumb {
437
+ display: flex;
438
+ align-items: center;
439
+ gap: 5px;
440
+ flex-wrap: wrap;
441
+ min-height: 32px;
442
+ }
443
+
444
+ .bc-link {
445
+ background: transparent;
446
+ border: none;
447
+ font-family: var(--font);
448
+ font-size: 13px;
449
+ color: var(--gray-color-ml);
450
+ cursor: pointer;
451
+ padding: 3px 8px;
452
+ border-radius: var(--radius-sm);
453
+ transition: all 0.12s ease;
454
+ display: inline-flex;
455
+ align-items: center;
456
+ gap: 4px;
457
+ font-weight: 500;
458
+ }
459
+
460
+ .bc-link:hover {
461
+ background: var(--primary-light-color-ml);
462
+ color: var(--primary-dark-color-ml);
463
+ }
464
+
465
+ .bc-link.current {
466
+ color: var(--dark-color-ml);
467
+ font-weight: 700;
468
+ cursor: default;
469
+ }
470
+
471
+ .bc-link.current:hover {
472
+ background: transparent;
473
+ }
474
+
475
+ .fm-breadcrumb .sep {
476
+ color: var(--gray-color-ml);
477
+ font-size: 13px;
478
+ user-select: none;
479
+ }
480
+
481
+ .fm-toolbar-actions {
482
+ display: flex;
483
+ align-items: center;
484
+ gap: 10px;
485
+ margin-left: auto;
486
+ }
487
+
488
+ /* Quick Filters */
489
+ .quick-filter-group {
490
+ display: inline-flex;
491
+ background: rgba(15, 118, 110, 0.06);
492
+ border: 1px solid var(--border-color);
493
+ border-radius: var(--radius);
494
+ padding: 2px;
495
+ }
496
+
497
+ .quick-filter-btn {
498
+ background: transparent;
499
+ border: none;
500
+ font-family: var(--font);
501
+ font-size: 12px;
502
+ font-weight: 600;
503
+ color: var(--text-secondary);
504
+ padding: 4px 11px;
505
+ border-radius: var(--radius-sm);
506
+ cursor: pointer;
507
+ transition: all 0.12s ease;
508
+ }
509
+
510
+ .quick-filter-btn:hover {
511
+ color: var(--primary-dark-color-ml);
512
+ }
513
+
514
+ .quick-filter-btn.active {
515
+ background: #ffffff;
516
+ color: var(--primary-color-ml);
517
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
518
+ }
519
+
520
+ /* Search Box */
521
+ .search-box {
522
+ position: relative;
523
+ width: 210px;
524
+ display: flex;
525
+ align-items: center;
526
+ }
527
+
528
+ .search-box .s-icon {
529
+ position: absolute;
530
+ left: 9px;
531
+ width: 14px;
532
+ height: 14px;
533
+ color: var(--gray-color-ml);
534
+ pointer-events: none;
535
+ }
536
+
537
+ .search-box input {
538
+ width: 100%;
539
+ padding: 6px 26px 6px 28px;
540
+ font-family: var(--font);
541
+ font-size: 12.5px;
542
+ border: 1px solid var(--border-color);
543
+ border-radius: var(--radius);
544
+ background: rgba(255, 255, 255, 0.85);
545
+ color: var(--dark-color-ml);
546
+ outline: none;
547
+ transition: all 0.15s ease;
548
+ }
549
+
550
+ .search-box input:focus {
551
+ border-color: var(--primary-color-ml);
552
+ background: #ffffff;
553
+ box-shadow: 0 0 0 3px var(--primary-light-color-ml);
554
+ }
555
+
556
+ .search-clear-btn {
557
+ position: absolute;
558
+ right: 6px;
559
+ background: transparent;
560
+ border: none;
561
+ color: var(--gray-color-ml);
562
+ cursor: pointer;
563
+ font-size: 16px;
564
+ line-height: 1;
565
+ padding: 2px 4px;
566
+ }
567
+
568
+ /* View Switcher */
569
+ .fm-view-toggle {
570
+ display: inline-flex;
571
+ border: 1px solid var(--border-color);
572
+ border-radius: var(--radius);
573
+ overflow: hidden;
574
+ background: #ffffff;
575
+ }
576
+
577
+ .view-btn {
578
+ width: 32px;
579
+ height: 30px;
580
+ border: none;
581
+ background: transparent;
582
+ cursor: pointer;
583
+ color: var(--gray-color-ml);
584
+ display: flex;
585
+ align-items: center;
586
+ justify-content: center;
587
+ transition: all 0.12s ease;
588
+ }
589
+
590
+ .view-btn:hover {
591
+ background: var(--light-color-ml);
592
+ color: var(--dark-color-ml);
593
+ }
594
+
595
+ .view-btn.active {
596
+ background: var(--primary-light-color-ml);
597
+ color: var(--primary-dark-color-ml);
598
+ }
599
+
600
+ /* File Grid Wrap & Items */
601
+ .fm-grid-wrap {
602
+ flex: 1 1 auto;
603
+ overflow-y: auto;
604
+ padding: 16px;
605
+ position: relative;
606
+ }
607
+
608
+ .fm-grid-wrap::-webkit-scrollbar {
609
+ width: 6px;
610
+ }
611
+ .fm-grid-wrap::-webkit-scrollbar-thumb {
612
+ background: var(--gray-light-color-ml);
613
+ border-radius: 3px;
614
+ }
615
+
616
+ /* Grid View */
617
+ .fm-grid.view-grid {
618
+ display: grid;
619
+ grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
620
+ grid-auto-rows: max-content;
621
+ align-content: start;
622
+ gap: 14px;
623
+ }
624
+
625
+ .fm-item {
626
+ position: relative;
627
+ background: rgba(255, 255, 255, 0.95);
628
+ border: 1px solid rgba(15, 118, 110, 0.15);
629
+ border-radius: var(--radius-lg);
630
+ cursor: pointer;
631
+ font-family: var(--font);
632
+ text-align: left;
633
+ transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
634
+ user-select: none;
635
+ }
636
+
637
+ .fm-item:hover {
638
+ border-color: var(--primary-color-ml);
639
+ transform: translateY(-2px);
640
+ box-shadow: 0 8px 20px rgba(15, 118, 110, 0.1);
641
+ }
642
+
643
+ .fm-item.is-selected {
644
+ border-color: var(--primary-color-ml);
645
+ background: var(--primary-light-color-ml);
646
+ }
647
+
648
+ /* Item styling in Grid View */
649
+ .fm-grid.view-grid .fm-item {
650
+ padding: 12px;
651
+ display: flex;
652
+ flex-direction: column;
653
+ align-items: flex-start;
654
+ gap: 8px;
655
+ }
656
+
657
+ .fm-grid.view-grid .fm-item-icon {
658
+ width: 100%;
659
+ aspect-ratio: 16 / 10;
660
+ border-radius: var(--radius);
661
+ display: flex;
662
+ align-items: center;
663
+ justify-content: center;
664
+ flex-shrink: 0;
665
+ background: var(--light-color-ml);
666
+ overflow: hidden;
667
+ position: relative;
668
+ }
669
+
670
+ .fm-item-thumb {
671
+ width: 100%;
672
+ height: 100%;
673
+ object-fit: cover;
674
+ }
675
+
676
+ .fm-item-icon .ext {
677
+ font-size: 13px;
678
+ font-weight: 700;
679
+ letter-spacing: 0.6px;
680
+ text-transform: uppercase;
681
+ }
682
+
683
+ .fm-item-icon .folder-svg {
684
+ width: 42px;
685
+ height: 42px;
686
+ }
687
+
688
+ .fm-grid.view-grid .fm-item-details {
689
+ width: 100%;
690
+ min-width: 0;
691
+ }
692
+
693
+ .fm-item-name {
694
+ font-size: 13px;
695
+ font-weight: 600;
696
+ color: var(--dark-color-ml);
697
+ overflow: hidden;
698
+ text-overflow: ellipsis;
699
+ white-space: nowrap;
700
+ min-width: 0;
701
+ }
702
+
703
+ .fm-item-meta {
704
+ font-size: 11.5px;
705
+ color: var(--gray-color-ml);
706
+ margin-top: 2px;
707
+ white-space: nowrap;
708
+ overflow: hidden;
709
+ text-overflow: ellipsis;
710
+ }
711
+
712
+ /* Star & Context Menu Buttons */
713
+ .fm-star {
714
+ position: absolute;
715
+ top: 8px;
716
+ left: 8px;
717
+ width: 24px;
718
+ height: 24px;
719
+ display: flex;
720
+ align-items: center;
721
+ justify-content: center;
722
+ cursor: pointer;
723
+ border-radius: 50%;
724
+ color: var(--text-disabled);
725
+ opacity: 0;
726
+ background: rgba(255, 255, 255, 0.9);
727
+ backdrop-filter: blur(4px);
728
+ transition: opacity 0.12s ease, color 0.12s ease;
729
+ z-index: 2;
730
+ border: none;
731
+ }
732
+
733
+ .fm-item:hover .fm-star,
734
+ .fm-item.starred .fm-star {
735
+ opacity: 1;
736
+ }
737
+
738
+ .fm-star.on {
739
+ color: var(--yellow);
740
+ opacity: 1;
741
+ }
742
+
743
+ .fm-star:hover {
744
+ color: var(--yellow);
745
+ transform: scale(1.1);
746
+ }
747
+
748
+ .fm-item-menu {
749
+ position: absolute;
750
+ top: 8px;
751
+ right: 8px;
752
+ width: 24px;
753
+ height: 24px;
754
+ border: none;
755
+ background: rgba(255, 255, 255, 0.9);
756
+ backdrop-filter: blur(4px);
757
+ border-radius: 50%;
758
+ display: flex;
759
+ align-items: center;
760
+ justify-content: center;
761
+ cursor: pointer;
762
+ color: var(--gray-color-ml);
763
+ opacity: 0;
764
+ transition: opacity 0.12s ease, background 0.12s ease, color 0.12s ease;
765
+ z-index: 2;
766
+ }
767
+
768
+ .fm-item:hover .fm-item-menu {
769
+ opacity: 1;
770
+ }
771
+
772
+ .fm-item-menu:hover {
773
+ background: #ffffff;
774
+ color: var(--primary-dark-color-ml);
775
+ box-shadow: var(--shadow-sm);
776
+ }
777
+
778
+ /* List View */
779
+ .fm-grid.view-list {
780
+ display: flex;
781
+ flex-direction: column;
782
+ gap: 4px;
783
+ }
784
+
785
+ .fm-grid.view-list .fm-item {
786
+ padding: 8px 14px;
787
+ display: grid;
788
+ grid-template-columns: 20px 32px 1fr 110px 140px 32px 32px;
789
+ gap: 12px;
790
+ align-items: center;
791
+ border-radius: var(--radius);
792
+ }
793
+
794
+ .fm-grid.view-list .fm-item-icon {
795
+ width: 32px;
796
+ height: 32px;
797
+ border-radius: var(--radius-sm);
798
+ display: flex;
799
+ align-items: center;
800
+ justify-content: center;
801
+ background: var(--light-color-ml);
802
+ }
803
+
804
+ .fm-grid.view-list .fm-item-icon .ext {
805
+ font-size: 10.5px;
806
+ font-weight: 700;
807
+ }
808
+
809
+ .fm-grid.view-list .fm-item-icon .folder-svg {
810
+ width: 22px;
811
+ height: 22px;
812
+ }
813
+
814
+ .fm-grid.view-list .fm-star,
815
+ .fm-grid.view-list .fm-item-menu {
816
+ position: static;
817
+ opacity: 1;
818
+ background: transparent;
819
+ }
820
+
821
+ .fm-grid.view-list .fm-item-meta {
822
+ font-size: 12px;
823
+ margin-top: 0;
824
+ }
825
+
826
+ /* Header row for list view */
827
+ .fm-list-header {
828
+ display: grid;
829
+ grid-template-columns: 20px 32px 1fr 110px 140px 32px 32px;
830
+ gap: 12px;
831
+ align-items: center;
832
+ padding: 6px 14px;
833
+ font-size: 11px;
834
+ font-weight: 700;
835
+ text-transform: uppercase;
836
+ letter-spacing: 0.5px;
837
+ color: var(--primary-dark-color-ml);
838
+ border-bottom: 1px solid var(--border-color);
839
+ margin-bottom: 4px;
840
+ }
841
+
842
+ /* Empty State */
843
+ .fm-empty {
844
+ padding: 80px 20px;
845
+ text-align: center;
846
+ color: var(--gray-color-ml);
847
+ display: flex;
848
+ flex-direction: column;
849
+ align-items: center;
850
+ justify-content: center;
851
+ }
852
+
853
+ .fm-empty[hidden],
854
+ [hidden] {
855
+ display: none !important;
856
+ }
857
+
858
+ .fm-empty svg {
859
+ color: var(--text-disabled);
860
+ margin-bottom: 12px;
861
+ }
862
+
863
+ .fm-empty .empty-title {
864
+ font-family: var(--font-headings);
865
+ font-size: 15px;
866
+ font-weight: 700;
867
+ color: var(--dark-color-ml);
868
+ margin-bottom: 4px;
869
+ }
870
+
871
+ .fm-empty .empty-desc {
872
+ font-size: 13px;
873
+ max-width: 360px;
874
+ }
875
+
876
+ /* Skeletons */
877
+ .fm-skeleton-grid {
878
+ display: grid;
879
+ grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
880
+ gap: 14px;
881
+ width: 100%;
882
+ }
883
+
884
+ .fm-skeleton-card {
885
+ background: rgba(255, 255, 255, 0.8);
886
+ border: 1px solid var(--border-color-light);
887
+ border-radius: var(--radius-lg);
888
+ padding: 12px;
889
+ display: flex;
890
+ flex-direction: column;
891
+ gap: 8px;
892
+ }
893
+
894
+ .fm-skeleton-icon {
895
+ width: 100%;
896
+ aspect-ratio: 16 / 10;
897
+ border-radius: var(--radius);
898
+ background: linear-gradient(90deg, #eaf2ee 25%, #dce8e3 50%, #eaf2ee 75%);
899
+ background-size: 200% 100%;
900
+ animation: fm-shimmer 1.5s infinite;
901
+ }
902
+
903
+ .fm-skeleton-line {
904
+ height: 12px;
905
+ border-radius: 4px;
906
+ background: linear-gradient(90deg, #eaf2ee 25%, #dce8e3 50%, #eaf2ee 75%);
907
+ background-size: 200% 100%;
908
+ animation: fm-shimmer 1.5s infinite;
909
+ }
910
+
911
+ .fm-skeleton-line.w-75 { width: 75%; }
912
+ .fm-skeleton-line.w-50 { width: 50%; }
913
+
914
+ @keyframes fm-shimmer {
915
+ 0% { background-position: 200% 0; }
916
+ 100% { background-position: -200% 0; }
917
+ }
918
+
919
+ /* Context Menu */
920
+ .fm-context-menu {
921
+ position: fixed;
922
+ z-index: 1000;
923
+ background: rgba(255, 255, 255, 0.95);
924
+ backdrop-filter: blur(12px);
925
+ border: 1px solid var(--border-color);
926
+ border-radius: var(--radius-lg);
927
+ box-shadow: var(--shadow-dropdown);
928
+ padding: 6px;
929
+ min-width: 175px;
930
+ animation: fm-menu-pop 0.12s cubic-bezier(0.16, 1, 0.3, 1);
931
+ }
932
+
933
+ @keyframes fm-menu-pop {
934
+ from { opacity: 0; transform: scale(0.95); }
935
+ to { opacity: 1; transform: scale(1); }
936
+ }
937
+
938
+ .fm-context-item {
939
+ display: flex;
940
+ align-items: center;
941
+ gap: 8px;
942
+ width: 100%;
943
+ padding: 7px 11px;
944
+ border: none;
945
+ background: transparent;
946
+ font-family: var(--font);
947
+ font-size: 12.5px;
948
+ font-weight: 500;
949
+ color: var(--dark-color-ml);
950
+ border-radius: var(--radius-sm);
951
+ cursor: pointer;
952
+ text-align: left;
953
+ transition: background 0.1s ease, color 0.1s ease;
954
+ }
955
+
956
+ .fm-context-item:hover {
957
+ background: var(--primary-light-color-ml);
958
+ color: var(--primary-dark-color-ml);
959
+ }
960
+
961
+ .fm-context-item.danger:hover {
962
+ background: var(--red-lt);
963
+ color: var(--danger-color-ml);
964
+ }
965
+
966
+ .fm-context-divider {
967
+ height: 1px;
968
+ background: var(--border-color-light);
969
+ margin: 4px 0;
970
+ }
971
+
972
+ /* Modals */
973
+ .modal {
974
+ display: none;
975
+ position: fixed;
976
+ inset: 0;
977
+ z-index: 1050;
978
+ overflow-x: hidden;
979
+ overflow-y: auto;
980
+ background: rgba(15, 42, 42, 0.45);
981
+ backdrop-filter: blur(6px);
982
+ align-items: center;
983
+ justify-content: center;
984
+ padding: 1rem;
985
+ }
986
+
987
+ .modal.show {
988
+ display: flex;
989
+ }
990
+
991
+ .modal-dialog {
992
+ position: relative;
993
+ width: 100%;
994
+ max-width: 480px;
995
+ margin: auto;
996
+ animation: modal-enter 0.2s cubic-bezier(0.16, 1, 0.3, 1);
997
+ }
998
+
999
+ .modal-dialog.modal-lg {
1000
+ max-width: 680px;
1001
+ }
1002
+
1003
+ .modal-dialog.preview-modal-dialog {
1004
+ max-width: 900px;
1005
+ }
1006
+
1007
+ .preview-modal-dialog.is-fullscreen {
1008
+ max-width: 98vw;
1009
+ height: 96vh;
1010
+ }
1011
+
1012
+ .preview-modal-dialog.is-fullscreen .modal-content {
1013
+ height: 100%;
1014
+ }
1015
+
1016
+ .preview-modal-dialog.is-fullscreen .preview-content {
1017
+ max-height: calc(96vh - 120px);
1018
+ }
1019
+
1020
+ @keyframes modal-enter {
1021
+ from { opacity: 0; transform: translateY(-12px) scale(0.98); }
1022
+ to { opacity: 1; transform: translateY(0) scale(1); }
1023
+ }
1024
+
1025
+ .modal-content {
1026
+ position: relative;
1027
+ display: flex;
1028
+ flex-direction: column;
1029
+ width: 100%;
1030
+ background: #ffffff;
1031
+ border: 1px solid var(--border-color);
1032
+ border-radius: var(--radius-xl);
1033
+ box-shadow: 0 20px 40px rgba(15, 42, 42, 0.16);
1034
+ outline: 0;
1035
+ }
1036
+
1037
+ .modal-header {
1038
+ display: flex;
1039
+ align-items: center;
1040
+ justify-content: space-between;
1041
+ padding: 14px 18px;
1042
+ border-bottom: 1px solid var(--border-color);
1043
+ }
1044
+
1045
+ .modal-title {
1046
+ font-family: var(--font-headings);
1047
+ display: flex;
1048
+ align-items: center;
1049
+ gap: 8px;
1050
+ font-size: 15px;
1051
+ font-weight: 700;
1052
+ color: var(--primary-dark-color-ml);
1053
+ margin: 0;
1054
+ }
1055
+
1056
+ .modal-title-icon {
1057
+ color: var(--primary-color-ml);
1058
+ }
1059
+
1060
+ .btn-close {
1061
+ background: transparent;
1062
+ border: none;
1063
+ font-size: 20px;
1064
+ line-height: 1;
1065
+ color: var(--gray-color-ml);
1066
+ cursor: pointer;
1067
+ padding: 4px;
1068
+ border-radius: var(--radius-sm);
1069
+ transition: all 0.12s ease;
1070
+ }
1071
+
1072
+ .btn-close:hover {
1073
+ color: var(--dark-color-ml);
1074
+ background: var(--light-color-ml);
1075
+ }
1076
+
1077
+ .modal-body {
1078
+ position: relative;
1079
+ flex: 1 1 auto;
1080
+ padding: 18px;
1081
+ }
1082
+
1083
+ .modal-footer {
1084
+ display: flex;
1085
+ align-items: center;
1086
+ justify-content: flex-end;
1087
+ gap: 8px;
1088
+ padding: 12px 18px;
1089
+ border-top: 1px solid var(--border-color);
1090
+ background: var(--light-color-ml);
1091
+ border-bottom-left-radius: var(--radius-xl);
1092
+ border-bottom-right-radius: var(--radius-xl);
1093
+ }
1094
+
1095
+ /* Upload Dropzone & Queue */
1096
+ .upload-drop-zone {
1097
+ border: 2px dashed var(--primary-color-ml);
1098
+ border-radius: var(--radius-lg);
1099
+ padding: 32px 20px;
1100
+ text-align: center;
1101
+ background: var(--primary-light-color-ml);
1102
+ cursor: pointer;
1103
+ transition: all 0.15s ease;
1104
+ }
1105
+
1106
+ .upload-drop-zone:hover,
1107
+ .upload-drop-zone.dragover {
1108
+ border-color: var(--primary-dark-color-ml);
1109
+ background: #c5efe7;
1110
+ }
1111
+
1112
+ .drop-icon {
1113
+ color: var(--primary-color-ml);
1114
+ margin-bottom: 10px;
1115
+ }
1116
+
1117
+ .drop-text {
1118
+ font-size: 14px;
1119
+ font-weight: 600;
1120
+ color: var(--dark-color-ml);
1121
+ }
1122
+
1123
+ .drop-browse-link {
1124
+ color: var(--primary-color-ml);
1125
+ text-decoration: underline;
1126
+ cursor: pointer;
1127
+ }
1128
+
1129
+ .drop-hint {
1130
+ font-size: 12px;
1131
+ color: var(--gray-color-ml);
1132
+ margin-top: 4px;
1133
+ }
1134
+
1135
+ .upload-queue {
1136
+ max-height: 200px;
1137
+ overflow-y: auto;
1138
+ display: flex;
1139
+ flex-direction: column;
1140
+ gap: 6px;
1141
+ }
1142
+
1143
+ .upload-queue-item {
1144
+ display: flex;
1145
+ align-items: center;
1146
+ justify-content: space-between;
1147
+ padding: 8px 12px;
1148
+ background: var(--light-color-ml);
1149
+ border: 1px solid var(--border-color);
1150
+ border-radius: var(--radius);
1151
+ font-size: 12.5px;
1152
+ }
1153
+
1154
+ .upload-queue-meta {
1155
+ color: var(--gray-color-ml);
1156
+ font-size: 11.5px;
1157
+ }
1158
+
1159
+ .progress-bar-wrap {
1160
+ height: 6px;
1161
+ background: var(--gray-light-color-ml);
1162
+ border-radius: 3px;
1163
+ overflow: hidden;
1164
+ }
1165
+
1166
+ .progress-bar-inner {
1167
+ height: 100%;
1168
+ background: var(--primary-color-ml);
1169
+ transition: width 0.2s ease;
1170
+ }
1171
+
1172
+ .upload-percent {
1173
+ font-size: 12px;
1174
+ font-weight: 700;
1175
+ color: var(--primary-color-ml);
1176
+ }
1177
+
1178
+ /* Modal Form Inputs */
1179
+ .form-label {
1180
+ font-size: 12.5px;
1181
+ font-weight: 600;
1182
+ color: var(--dark-color-ml);
1183
+ margin-bottom: 6px;
1184
+ display: block;
1185
+ }
1186
+
1187
+ .form-control {
1188
+ width: 100%;
1189
+ padding: 8px 12px;
1190
+ font-family: var(--font);
1191
+ font-size: 13px;
1192
+ color: var(--dark-color-ml);
1193
+ background: #ffffff;
1194
+ border: 1px solid var(--border-color);
1195
+ border-radius: var(--radius);
1196
+ outline: none;
1197
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
1198
+ }
1199
+
1200
+ .form-control:focus {
1201
+ border-color: var(--primary-color-ml);
1202
+ box-shadow: 0 0 0 3px var(--primary-light-color-ml);
1203
+ }
1204
+
1205
+ .form-text {
1206
+ font-size: 11.5px;
1207
+ color: var(--gray-color-ml);
1208
+ margin-top: 4px;
1209
+ }
1210
+
1211
+ /* Preview Modal Content */
1212
+ .preview-content {
1213
+ max-height: 70vh;
1214
+ overflow: auto;
1215
+ display: flex;
1216
+ align-items: center;
1217
+ justify-content: center;
1218
+ background: #152222;
1219
+ min-height: 280px;
1220
+ }
1221
+
1222
+ .preview-content img {
1223
+ max-width: 100%;
1224
+ max-height: 70vh;
1225
+ object-fit: contain;
1226
+ }
1227
+
1228
+ .preview-content video,
1229
+ .preview-content audio {
1230
+ max-width: 100%;
1231
+ max-height: 70vh;
1232
+ }
1233
+
1234
+ .preview-code-block {
1235
+ width: 100%;
1236
+ height: 100%;
1237
+ max-height: 70vh;
1238
+ margin: 0;
1239
+ padding: 16px;
1240
+ background: #1a2828;
1241
+ color: #f4f7f3;
1242
+ font-family: var(--font-mono);
1243
+ font-size: 12.5px;
1244
+ overflow: auto;
1245
+ line-height: 1.5;
1246
+ }
1247
+
1248
+ .preview-iframe {
1249
+ width: 100%;
1250
+ height: 70vh;
1251
+ border: none;
1252
+ }
1253
+
1254
+ .preview-actions {
1255
+ display: flex;
1256
+ align-items: center;
1257
+ gap: 8px;
1258
+ }
1259
+
1260
+ /* Toast Container & Notifications */
1261
+ .toast-container {
1262
+ position: fixed;
1263
+ bottom: 20px;
1264
+ right: 20px;
1265
+ z-index: 1100;
1266
+ display: flex;
1267
+ flex-direction: column;
1268
+ gap: 8px;
1269
+ pointer-events: none;
1270
+ }
1271
+
1272
+ .toast-notification {
1273
+ pointer-events: auto;
1274
+ display: flex;
1275
+ align-items: center;
1276
+ gap: 10px;
1277
+ padding: 10px 16px;
1278
+ border-radius: var(--radius);
1279
+ background: var(--dark-color-ml);
1280
+ color: #ffffff;
1281
+ font-family: var(--font);
1282
+ font-size: 13px;
1283
+ font-weight: 500;
1284
+ box-shadow: var(--shadow-lg);
1285
+ min-width: 260px;
1286
+ max-width: 400px;
1287
+ transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.25s ease;
1288
+ }
1289
+
1290
+ .toast-notification.success {
1291
+ background: linear-gradient(135deg, #10b981, #059669);
1292
+ }
1293
+
1294
+ .toast-notification.error {
1295
+ background: linear-gradient(135deg, #ef4444, #dc2626);
1296
+ }
1297
+
1298
+ .toast-notification.warning {
1299
+ background: linear-gradient(135deg, #f59e0b, #d97706);
1300
+ }
1301
+
1302
+ .toast-close-btn {
1303
+ margin-left: auto;
1304
+ background: transparent;
1305
+ border: none;
1306
+ color: rgba(255, 255, 255, 0.85);
1307
+ cursor: pointer;
1308
+ font-size: 16px;
1309
+ line-height: 1;
1310
+ }
1311
+
1312
+ /* Pagination */
1313
+ .pagination-container {
1314
+ padding: 12px 16px;
1315
+ border-top: 1px solid var(--border-color);
1316
+ display: flex;
1317
+ align-items: center;
1318
+ justify-content: flex-end;
1319
+ }
1320
+
1321
+ .pagination {
1322
+ display: flex;
1323
+ align-items: center;
1324
+ gap: 4px;
1325
+ list-style: none;
1326
+ margin: 0;
1327
+ padding: 0;
1328
+ }
1329
+
1330
+ .page-item .page-link {
1331
+ display: flex;
1332
+ align-items: center;
1333
+ justify-content: center;
1334
+ min-width: 28px;
1335
+ height: 28px;
1336
+ padding: 0 6px;
1337
+ border-radius: var(--radius-sm);
1338
+ border: 1px solid var(--border-color);
1339
+ background: #ffffff;
1340
+ color: var(--text-secondary);
1341
+ font-size: 12px;
1342
+ font-weight: 600;
1343
+ text-decoration: none;
1344
+ cursor: pointer;
1345
+ transition: all 0.12s ease;
1346
+ }
1347
+
1348
+ .page-item .page-link:hover {
1349
+ background: var(--primary-light-color-ml);
1350
+ color: var(--primary-dark-color-ml);
1351
+ }
1352
+
1353
+ .page-item.active .page-link {
1354
+ background: var(--primary-color-ml);
1355
+ border-color: var(--primary-color-ml);
1356
+ color: #ffffff;
1357
+ }
1358
+
1359
+ .page-item.disabled .page-link {
1360
+ opacity: 0.4;
1361
+ cursor: not-allowed;
1362
+ }
1363
+
1364
+ /* Mobile & Tablet Responsiveness */
1365
+ @media (max-width: 900px) {
1366
+ .fm-layout {
1367
+ grid-template-columns: 1fr;
1368
+ height: auto;
1369
+ max-height: none;
1370
+ }
1371
+
1372
+ .fm-tree-wrap {
1373
+ display: none;
1374
+ }
1375
+
1376
+ .fm-grid-wrap {
1377
+ min-height: 400px;
1378
+ }
1379
+ }
1380
+
1381
+ @media (max-width: 640px) {
1382
+ .page-header-row {
1383
+ flex-direction: column;
1384
+ align-items: flex-start;
1385
+ }
1386
+
1387
+ .page-actions {
1388
+ width: 100%;
1389
+ justify-content: flex-start;
1390
+ }
1391
+
1392
+ .fm-toolbar {
1393
+ flex-direction: column;
1394
+ align-items: stretch;
1395
+ }
1396
+
1397
+ .fm-toolbar-actions {
1398
+ width: 100%;
1399
+ justify-content: space-between;
1400
+ flex-wrap: wrap;
1401
+ }
1402
+
1403
+ .search-box {
1404
+ width: 100%;
1405
+ }
1406
+
1407
+ .fm-grid.view-list .fm-item {
1408
+ grid-template-columns: 32px 1fr 32px;
1409
+ }
1410
+
1411
+ .fm-grid.view-list .fm-item-size,
1412
+ .fm-grid.view-list .fm-item-date,
1413
+ .fm-grid.view-list .fm-item-checkbox {
1414
+ display: none;
1415
+ }
1416
+
1417
+ .fm-list-header {
1418
+ display: none;
1419
+ }
1420
+ }