Seregon/zftpd

Zero-copy FTP/HTTP Daemon compatible with all POSIX systems

C/11.0 KB/No license
web/css/dashboard.css
zftpd / web / css / dashboard.css
1/* ══ PS5 HUB DASHBOARD REVOLUTION ═════════════════════════════════════════
2 * Premium, glassmorphism-heavy dashboard redesign.
3 * ═════════════════════════════════════════════════════════════════════════ */
4 
5.dash {
6 max-width: 1200px;
7 margin: 0 auto;
8 padding: 0 0 40px 0;
9 display: flex;
10 flex-direction: column;
11 gap: 32px;
12}
13 
14/* ── Section Structure ── */
15.dash-section {
16 background: var(--sf);
17 border: 1px solid var(--bd);
18 border-radius: var(--radius-lg);
19 padding: 24px;
20 box-shadow: var(--card-shadow);
21 position: relative;
22 overflow: hidden;
23}
24 
25/* Accent top border for sections */
26.dash-section::before {
27 content: '';
28 position: absolute;
29 top: 0; left: 0; right: 0;
30 height: 2px;
31 background: linear-gradient(90deg, var(--ac), transparent);
32 opacity: 0.5;
33}
34 
35.dash-section-title {
36 display: flex;
37 align-items: center;
38 gap: 12px;
39 font-size: 16px;
40 font-weight: 700;
41 color: var(--tx);
42 margin-bottom: 20px;
43}
44 
45.dash-section-title svg {
46 color: var(--ac);
47 width: 20px;
48 height: 20px;
49 filter: drop-shadow(0 0 4px rgba(43,140,255, 0.4));
50}
51 
52.dash-section-title .dash-see-all {
53 margin-left: auto;
54 font-size: 12px;
55 font-weight: 600;
56 color: var(--tx3);
57 cursor: pointer;
58 padding: 6px 12px;
59 border-radius: var(--radius-pill);
60 background: rgba(255, 255, 255, 0.05);
61 transition: all var(--transition-fast);
62}
63 
64.dash-section-title .dash-see-all:hover {
65 color: #fff;
66 background: var(--ac);
67 box-shadow: var(--glow-sm);
68}
69 
70/* ── Hero Banner ── */
71.dash-hero-container {
72 display: flex;
73 flex-direction: column;
74 gap: 24px;
75 margin-bottom: 24px;
76}
77 
78.dash-hero-banner {
79 position: relative;
80 width: 100%;
81 height: 320px;
82 border-radius: var(--radius-lg);
83 overflow: hidden;
84 background: var(--sf2);
85 display: flex;
86 box-shadow: var(--card-shadow);
87 border: 1px solid var(--ac);
88}
89 
90.dash-hero-bg {
91 position: absolute;
92 top: 0; left: 0; right: 0; bottom: 0;
93 background-size: cover;
94 background-position: center;
95 filter: blur(12px) brightness(0.3);
96 transform: scale(1.1); /* hide blurred edges */
97 z-index: 1;
98}
99 
100.dash-hero-content {
101 position: relative;
102 z-index: 2;
103 display: flex;
104 align-items: flex-end;
105 padding: 40px;
106 width: 100%;
107 background: linear-gradient(to top, rgba(0,0,0,0.95) 0%, rgba(0,0,0,0.3) 60%, transparent 100%);
108}
109 
110.dash-hero-cover {
111 width: 180px;
112 height: 180px;
113 border-radius: var(--radius-md);
114 box-shadow: 0 16px 48px rgba(0,0,0,0.8);
115 border: 2px solid rgba(255,255,255,0.15);
116 object-fit: cover;
117 margin-right: 32px;
118}
119 
120.dash-hero-info {
121 flex: 1;
122 display: flex;
123 flex-direction: column;
124 gap: 8px;
125 margin-bottom: 10px;
126}
127 
128.dash-hero-meta {
129 font-size: 11px;
130 font-weight: 700;
131 color: var(--ac);
132 text-transform: uppercase;
133 letter-spacing: 0.1em;
134}
135 
136.dash-hero-title {
137 font-size: 32px;
138 font-weight: 800;
139 color: #fff;
140 line-height: 1.1;
141 text-shadow: 0 4px 12px rgba(0,0,0,0.5);
142}
143 
144.dash-hero-id {
145 font-size: 14px;
146 color: rgba(255,255,255,0.7);
147 font-weight: 500;
148}
149 
150.dash-hero-actions {
151 margin-left: auto;
152 margin-bottom: 20px;
153}
154 
155/* ── Game Cards Scroll ── */
156.dash-games-row {
157 display: flex;
158 gap: 16px;
159 overflow-x: auto;
160 padding-bottom: 16px;
161 scrollbar-width: none;
162 scroll-snap-type: x mandatory;
163}
164 
165.dash-games-row::-webkit-scrollbar { display: none; }
166 
167.dash-game-card {
168 flex-shrink: 0;
169 width: 160px;
170 cursor: pointer;
171 border-radius: var(--radius-md);
172 overflow: hidden;
173 background: rgba(255,255,255,0.02);
174 border: 1px solid var(--bd);
175 transition: transform .2s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow .2s;
176 scroll-snap-align: start;
177 position: relative;
178 box-shadow: 0 4px 12px rgba(0,0,0,0.2);
179}
180 
181.dash-game-card:hover {
182 transform: translateY(-6px) scale(1.02);
183 box-shadow: 0 16px 32px rgba(0,0,0,0.4), 0 0 12px rgba(43,140,255,0.2);
184 border-color: rgba(255,255,255,0.2);
185 background: rgba(255,255,255,0.05);
186}
187 
188.dash-game-cover {
189 width: 100%;
190 height: 160px;
191 object-fit: cover;
192 background: rgba(0,0,0,0.2);
193 display: block;
194}
195 
196.dash-game-cover.placeholder {
197 display: flex;
198 align-items: center;
199 justify-content: center;
200 color: var(--tx3);
201 font-size: 32px;
202}
203 
204.dash-game-info {
205 padding: 12px;
206}
207 
208.dash-game-title {
209 font-size: 12px;
210 font-weight: 600;
211 color: var(--tx);
212 overflow: hidden;
213 text-overflow: ellipsis;
214 white-space: nowrap;
215 margin-bottom: 4px;
216}
217 
218.dash-game-id {
219 font-size: 10px;
220 color: var(--tx3);
221 font-weight: 500;
222}
223 
224/* Location Badge */
225.dash-loc-badge {
226 position: absolute;
227 top: 8px;
228 right: 8px;
229 background: rgba(0,0,0,0.7);
230 backdrop-filter: blur(4px);
231 -webkit-backdrop-filter: blur(4px);
232 border: 1px solid rgba(255,255,255,0.15);
233 color: #fff;
234 font-size: 10px;
235 font-weight: 700;
236 padding: 4px 8px;
237 border-radius: var(--radius-pill);
238 box-shadow: 0 2px 8px rgba(0,0,0,0.5);
239 z-index: 10;
240}
241 
242/* ── Layout: Two Columns for Actions/Stats & Recent ── */
243.dash-grid-2col {
244 display: grid;
245 grid-template-columns: 1fr 1fr;
246 gap: 32px;
247}
248@media (max-width: 900px) {
249 .dash-grid-2col {
250 grid-template-columns: 1fr;
251 }
252}
253 
254/* ── Quick Actions (Pills) ── */
255.dash-actions-grid {
256 display: grid;
257 grid-template-columns: repeat(2, 1fr);
258 gap: 12px;
259}
260 
261.dash-action-pill {
262 display: flex;
263 align-items: center;
264 gap: 12px;
265 padding: 16px;
266 background: rgba(255,255,255,0.03);
267 border: 1px solid var(--bd);
268 border-radius: var(--radius-md);
269 cursor: pointer;
270 transition: all var(--transition-fast);
271}
272 
273.dash-action-pill:hover {
274 background: rgba(255,255,255,0.08);
275 transform: translateY(-2px);
276 border-color: rgba(255,255,255,0.2);
277 box-shadow: 0 8px 16px rgba(0,0,0,0.2);
278}
279 
280.dash-action-pill-ico {
281 width: 36px;
282 height: 36px;
283 border-radius: 10px;
284 display: flex;
285 align-items: center;
286 justify-content: center;
287 flex-shrink: 0;
288}
289 
290.dash-action-pill-ico.blue { background: rgba(43, 140, 255, 0.15); color: #2b8cff; }
291.dash-action-pill-ico.green { background: rgba(46, 204, 113, 0.15); color: #2ecc71; }
292.dash-action-pill-ico.orange { background: rgba(240, 165, 0, 0.15); color: #f0a500; }
293.dash-action-pill-ico.purple { background: rgba(124, 77, 255, 0.15); color: #7c4dff; }
294 
295.dash-action-pill-text {
296 font-size: 13px;
297 font-weight: 600;
298 color: var(--tx);
299}
300 
301/* ── Stats (Circular Rings) ── */
302.dash-stats-flex {
303 display: flex;
304 gap: 24px;
305 margin-top: 24px;
306}
307 
308.dash-stat-ring-container {
309 flex: 1;
310 display: flex;
311 flex-direction: column;
312 align-items: center;
313 background: rgba(0,0,0,0.15);
314 border-radius: 16px;
315 padding: 20px 10px;
316 border: 1px solid rgba(255,255,255,0.05);
317}
318 
319.dash-stat-ring {
320 position: relative;
321 width: 80px;
322 height: 80px;
323 margin-bottom: 16px;
324}
325 
326.dash-stat-ring svg {
327 width: 100%;
328 height: 100%;
329 transform: rotate(-90deg);
330}
331 
332.dash-stat-ring-bg {
333 fill: none;
334 stroke: rgba(255,255,255,0.05);
335 stroke-width: 6;
336}
337 
338.dash-stat-ring-fg {
339 fill: none;
340 stroke: var(--ac);
341 stroke-width: 6;
342 stroke-linecap: round;
343 stroke-dasharray: 220; /* 2 * pi * r (r=35) approximated */
344 stroke-dashoffset: 220;
345 transition: stroke-dashoffset 1s cubic-bezier(0.4, 0, 0.2, 1);
346}
347 
348.dash-stat-ring-fg.wn { stroke: var(--wn); }
349.dash-stat-ring-fg.cr { stroke: var(--er); }
350 
351.dash-stat-ring-val {
352 position: absolute;
353 top: 0; left: 0; right: 0; bottom: 0;
354 display: flex;
355 align-items: center;
356 justify-content: center;
357 font-size: 18px;
358 font-weight: 700;
359 color: var(--tx);
360}
361 
362.dash-stat-label {
363 font-size: 11px;
364 font-weight: 600;
365 color: var(--tx2);
366 text-transform: uppercase;
367 letter-spacing: 0.1em;
368 margin-bottom: 4px;
369}
370 
371.dash-stat-sub {
372 font-size: 10px;
373 color: var(--tx3);
374 text-align: center;
375}
376 
377/* ── Recent Files ── */
378.dash-recent-list {
379 display: flex;
380 flex-direction: column;
381 gap: 6px;
382}
383 
384.dash-recent-item {
385 display: flex;
386 align-items: center;
387 gap: 12px;
388 padding: 10px 16px;
389 background: rgba(255,255,255,0.02);
390 border: 1px solid transparent;
391 border-radius: var(--radius-md);
392 cursor: pointer;
393 transition: all var(--transition-fast);
394}
395 
396.dash-recent-item:hover {
397 background: rgba(255,255,255,0.06);
398 border-color: rgba(255,255,255,0.1);
399 transform: translateX(4px);
400}
401 
402.dash-recent-ico {
403 width: 32px;
404 height: 32px;
405 border-radius: 8px;
406 display: flex;
407 align-items: center;
408 justify-content: center;
409 background: rgba(255,255,255,0.05);
410 flex-shrink: 0;
411}
412 
413.dash-recent-name {
414 flex: 1;
415 font-size: 13px;
416 font-weight: 500;
417 color: var(--tx);
418 overflow: hidden;
419 text-overflow: ellipsis;
420 white-space: nowrap;
421}
422 
423.dash-recent-size {
424 font-size: 11px;
425 color: var(--tx3);
426 white-space: nowrap;
427}
428 
429/* ── Dedup Location Dropdown ── */
430.dash-loc-dropdown {
431 position: fixed;
432 top: 0; left: 0; right: 0; bottom: 0;
433 background: rgba(0,0,0,0.6);
434 backdrop-filter: blur(8px);
435 -webkit-backdrop-filter: blur(8px);
436 z-index: 10000;
437 display: flex;
438 align-items: center;
439 justify-content: center;
440 flex-direction: column;
441}
442 
443.dash-loc-box {
444 background: var(--bg);
445 border: 1px solid var(--bd);
446 border-radius: var(--radius-lg);
447 padding: 24px;
448 width: 480px;
449 max-width: 90%;
450 box-shadow: 0 24px 64px rgba(0,0,0,0.8);
451}
452 
453.dash-loc-box-title {
454 font-size: 20px;
455 font-weight: 700;
456 margin-bottom: 8px;
457 color: #fff;
458 display: flex;
459 justify-content: space-between;
460 align-items: center;
461}
462 
463.dash-loc-box-title span.close-btn {
464 cursor: pointer;
465 color: var(--tx3);
466 font-size: 24px;
467}
468 
469.dash-loc-box-title span.close-btn:hover {
470 color: #fff;
471}
472 
473.dash-loc-box-sub {
474 font-size: 13px;
475 color: var(--tx2);
476 margin-bottom: 24px;
477}
478 
479.dash-loc-list {
480 display: flex;
481 flex-direction: column;
482 gap: 8px;
483}
484 
485.dash-loc-list-item {
486 display: flex;
487 align-items: center;
488 padding: 16px;
489 background: rgba(255,255,255,0.03);
490 border: 1px solid rgba(255,255,255,0.05);
491 border-radius: var(--radius-md);
492 cursor: pointer;
493 transition: all .15s;
494}
495 
496.dash-loc-list-item:hover {
497 background: rgba(43,140,255,0.1);
498 border-color: var(--ac);
499}
500 
501.dash-loc-drive {
502 background: var(--tx);
503 color: var(--bg);
504 font-size: 10px;
505 font-weight: 800;
506 padding: 4px 8px;
507 border-radius: 4px;
508 margin-right: 16px;
509 text-transform: uppercase;
510 letter-spacing: 0.05em;
511}
512 
513.dash-loc-path {
514 font-size: 13px;
515 color: var(--tx);
516 overflow: hidden;
517 text-overflow: ellipsis;
518 white-space: nowrap;
519 flex: 1;
520}
521 
522.dash-loc-size {
523 font-size: 11px;
524 color: var(--tx3);
525 margin-left: 12px;
526}
527 
528/* ── Skeleton Loaders ── */
529@keyframes dash-shimmer {
530 0% { transform: translateX(-100%); }
531 100% { transform: translateX(100%); }
532}
533.shimmer {
534 position: relative;
535 overflow: hidden;
536 background-color: var(--sf) !important;
537}
538.shimmer::after {
539 content: '';
540 position: absolute;
541 top: 0; left: 0; right: 0; bottom: 0;
542 background: linear-gradient(90deg, transparent, rgba(255,255,255,0.06), transparent);
543 animation: dash-shimmer 2s infinite;
544}
545