Zero-copy FTP/HTTP Daemon compatible with all POSIX systems
| 1 | /* ══ FILE LIST HEADER ═════════════════════════════════════════════════════ */ |
| 2 | |
| 3 | .fl-header { |
| 4 | display: flex; |
| 5 | align-items: center; |
| 6 | margin-bottom: 12px; |
| 7 | } |
| 8 | |
| 9 | .fl-count { |
| 10 | font-size: 11px; |
| 11 | color: var(--tx3); |
| 12 | } |
| 13 | |
| 14 | .fl-count b { |
| 15 | color: var(--ac); |
| 16 | font-weight: 700; |
| 17 | } |
| 18 | |
| 19 | /* ══ FILE TYPE ICON COLORS ════════════════════════════════════════════════ */ |
| 20 | |
| 21 | .fi-wrap { |
| 22 | width: 100%; |
| 23 | height: 100%; |
| 24 | display: flex; |
| 25 | align-items: center; |
| 26 | justify-content: center; |
| 27 | } |
| 28 | |
| 29 | .fi-dir { color: #4da6ff; } |
| 30 | .fi-code { color: #f7c948; } |
| 31 | .fi-web { color: #4fc3f7; } |
| 32 | .fi-style { color: #f06292; } |
| 33 | .fi-data { color: #81c784; } |
| 34 | .fi-doc { color: #90caf9; } |
| 35 | .fi-img { color: #ce93d8; } |
| 36 | .fi-video { color: #ff8a65; } |
| 37 | .fi-audio { color: #a5d6a7; } |
| 38 | .fi-arch { color: #ffb74d; } |
| 39 | .fi-script { color: #80cbc4; } |
| 40 | .fi-bin { color: #ef9a9a; } |
| 41 | .fi-db { color: #80deea; } |
| 42 | .fi-lock { color: #ffe082; } |
| 43 | .fi-log { color: #b0bec5; } |
| 44 | .fi-sheet { color: #a5d6a7; } |
| 45 | .fi-slide { color: #ffab40; } |
| 46 | .fi-game { color: #7c4dff; } |
| 47 | .fi-generic { color: var(--tx2); } |
| 48 | |
| 49 | /* ══ GRID VIEW ════════════════════════════════════════════════════════════ */ |
| 50 | |
| 51 | .fl.vg-grid { |
| 52 | display: grid; |
| 53 | grid-template-columns: repeat(auto-fill, minmax(152px, 1fr)); |
| 54 | gap: 9px; |
| 55 | } |
| 56 | |
| 57 | .fl.vg-grid .card { |
| 58 | display: flex; |
| 59 | flex-direction: column; |
| 60 | align-items: center; |
| 61 | gap: 8px; |
| 62 | padding: 16px 12px 11px; |
| 63 | border: 1px solid var(--bd); |
| 64 | background: var(--sf); |
| 65 | border-radius: 13px; |
| 66 | cursor: pointer; |
| 67 | text-align: center; |
| 68 | transition: border-color .15s, background .15s, transform .2s, box-shadow .2s; |
| 69 | position: relative; |
| 70 | overflow: hidden; |
| 71 | } |
| 72 | |
| 73 | .fl.vg-grid .card::before { |
| 74 | content: ''; |
| 75 | position: absolute; |
| 76 | inset: 0; |
| 77 | opacity: 0; |
| 78 | pointer-events: none; |
| 79 | background: radial-gradient(ellipse at 50% -10%, rgba(var(--acR), .18), transparent 65%); |
| 80 | transition: opacity .2s; |
| 81 | } |
| 82 | |
| 83 | .fl.vg-grid .card:hover { |
| 84 | border-color: var(--ac); |
| 85 | background: var(--sf2); |
| 86 | transform: translateY(-3px); |
| 87 | box-shadow: 0 10px 32px rgba(0, 0, 0, .4), 0 0 0 1px rgba(var(--acR), .35); |
| 88 | } |
| 89 | |
| 90 | .fl.vg-grid .card:hover::before { opacity: 1; } |
| 91 | |
| 92 | /* Game card with cover art */ |
| 93 | .fl.vg-grid .card.game-card { |
| 94 | padding: 0; |
| 95 | overflow: hidden; |
| 96 | } |
| 97 | |
| 98 | .fl.vg-grid .card.game-card .card-cover { |
| 99 | width: 100%; |
| 100 | height: 152px; /* Set a fixed height as min-width is 152px */ |
| 101 | object-fit: cover; |
| 102 | border-radius: 12px 12px 0 0; |
| 103 | } |
| 104 | |
| 105 | .fl.vg-grid .card.game-card .card-info { |
| 106 | padding: 8px 10px 10px; |
| 107 | width: 100%; |
| 108 | } |
| 109 | |
| 110 | .c-ico { |
| 111 | width: 50px; |
| 112 | height: 50px; |
| 113 | border-radius: 13px; |
| 114 | display: flex; |
| 115 | align-items: center; |
| 116 | justify-content: center; |
| 117 | background: var(--gw); |
| 118 | border: 1px solid rgba(255, 255, 255, .06); |
| 119 | } |
| 120 | |
| 121 | .c-name { |
| 122 | font-size: 12px; |
| 123 | font-weight: 600; |
| 124 | width: 100%; |
| 125 | overflow: hidden; |
| 126 | text-overflow: ellipsis; |
| 127 | white-space: nowrap; |
| 128 | } |
| 129 | |
| 130 | .c-meta { |
| 131 | display: flex; |
| 132 | align-items: center; |
| 133 | justify-content: center; |
| 134 | gap: 5px; |
| 135 | flex-wrap: wrap; |
| 136 | width: 100%; |
| 137 | min-height: 18px; |
| 138 | } |
| 139 | |
| 140 | /* ══ LIST VIEW ════════════════════════════════════════════════════════════ */ |
| 141 | |
| 142 | .fl.vg-list { |
| 143 | display: flex; |
| 144 | flex-direction: column; |
| 145 | gap: 3px; |
| 146 | } |
| 147 | |
| 148 | .fl.vg-list .card { |
| 149 | display: flex; |
| 150 | align-items: center; |
| 151 | gap: 10px; |
| 152 | padding: 9px 14px; |
| 153 | border: 1px solid var(--bd); |
| 154 | background: var(--sf); |
| 155 | border-radius: 9px; |
| 156 | cursor: pointer; |
| 157 | transition: border-color .12s, background .12s; |
| 158 | } |
| 159 | |
| 160 | .fl.vg-list .card:hover { |
| 161 | border-color: var(--ac); |
| 162 | background: var(--sf2); |
| 163 | } |
| 164 | |
| 165 | .fl.vg-list .c-ico { |
| 166 | width: 32px; |
| 167 | height: 32px; |
| 168 | border-radius: 8px; |
| 169 | flex-shrink: 0; |
| 170 | background: var(--gw); |
| 171 | border: 1px solid rgba(255, 255, 255, .05); |
| 172 | } |
| 173 | |
| 174 | .fl.vg-list .c-name { |
| 175 | font-size: 13px; |
| 176 | font-weight: 600; |
| 177 | flex: 1; |
| 178 | overflow: hidden; |
| 179 | text-overflow: ellipsis; |
| 180 | white-space: nowrap; |
| 181 | } |
| 182 | |
| 183 | .c-right { |
| 184 | display: flex; |
| 185 | align-items: center; |
| 186 | gap: 8px; |
| 187 | flex-shrink: 0; |
| 188 | } |
| 189 | |
| 190 | /* ══ DETAILS VIEW (TABLE) ═════════════════════════════════════════════════ */ |
| 191 | |
| 192 | .fl.vg-details { display: block; } |
| 193 | |
| 194 | .dtbl { |
| 195 | width: 100%; |
| 196 | border-collapse: collapse; |
| 197 | } |
| 198 | |
| 199 | .dtbl thead th { |
| 200 | text-align: left; |
| 201 | font-size: 10px; |
| 202 | font-weight: 600; |
| 203 | color: var(--tx3); |
| 204 | text-transform: uppercase; |
| 205 | letter-spacing: .08em; |
| 206 | padding: 8px 14px; |
| 207 | border-bottom: 1px solid var(--bd2); |
| 208 | cursor: pointer; |
| 209 | user-select: none; |
| 210 | white-space: nowrap; |
| 211 | } |
| 212 | |
| 213 | .dtbl thead th:hover { color: var(--ac); } |
| 214 | .sort-a { color: var(--ac); margin-left: 3px; font-size: 10px; } |
| 215 | |
| 216 | .dtbl tbody tr { |
| 217 | border-bottom: 1px solid var(--bd); |
| 218 | cursor: pointer; |
| 219 | transition: background .1s; |
| 220 | } |
| 221 | |
| 222 | .dtbl tbody tr:hover { background: var(--sf2); } |
| 223 | |
| 224 | .dtbl tbody td { |
| 225 | padding: 9px 14px; |
| 226 | font-size: 12px; |
| 227 | vertical-align: middle; |
| 228 | } |
| 229 | |
| 230 | .t-ic { width: 36px; text-align: center; } |
| 231 | .t-nm { font-weight: 600; max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| 232 | .t-ex { width: 72px; } |
| 233 | .t-sz { width: 88px; color: var(--tx2); white-space: nowrap; } |
| 234 | .t-dt { color: var(--tx2); white-space: nowrap; font-size: 11px; } |
| 235 | .t-tp { width: 76px; color: var(--tx3); font-size: 11px; white-space: nowrap; } |
| 236 | |
| 237 | /* ══ EMPTY / LOADING / ERROR STATES ═══════════════════════════════════════ */ |
| 238 | |
| 239 | .s-card { |
| 240 | grid-column: 1/-1; |
| 241 | display: flex; |
| 242 | flex-direction: column; |
| 243 | align-items: center; |
| 244 | justify-content: center; |
| 245 | gap: 10px; |
| 246 | padding: 52px 24px; |
| 247 | border-radius: var(--radius-md); |
| 248 | border: 1px solid var(--bd); |
| 249 | background: var(--sf); |
| 250 | color: var(--tx2); |
| 251 | font-size: 13px; |
| 252 | } |
| 253 | |
| 254 | .s-ico { opacity: .4; color: var(--tx2); } |
| 255 | |
| 256 | .s-err { |
| 257 | border-color: rgba(255, 95, 87, .28); |
| 258 | background: rgba(255, 95, 87, .05); |
| 259 | color: #ffb0ab; |
| 260 | } |
| 261 | |
| 262 | .s-err .s-ico { opacity: .9; color: #ff8080; } |
| 263 | |
| 264 | /* ══ MOBILE ACTION BUTTON ═════════════════════════════════════════════════ */ |
| 265 | |
| 266 | .c-action { |
| 267 | display: none; |
| 268 | align-items: center; |
| 269 | justify-content: center; |
| 270 | width: 28px; |
| 271 | height: 28px; |
| 272 | border-radius: 6px; |
| 273 | border: 1px solid var(--bd2); |
| 274 | background: var(--sf2); |
| 275 | color: var(--tx2); |
| 276 | font-size: 16px; |
| 277 | font-weight: 700; |
| 278 | cursor: pointer; |
| 279 | flex-shrink: 0; |
| 280 | line-height: 1; |
| 281 | letter-spacing: 1px; |
| 282 | } |
| 283 | |
| 284 | .c-action:hover { |
| 285 | border-color: var(--ac); |
| 286 | color: var(--tx); |
| 287 | } |
| 288 |