Spaces:
Paused
Paused
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>PixelDrive — Partage sécurisé</title> | |
| __OG_META__ | |
| <style> | |
| :root{--bg:#0d0f1a;--panel:#151827;--border:#262a3f;--primary:#6366f1;--text:#f4f4f5;--muted:#9aa0b4;--danger:#ef4444;--radius:12px} | |
| *{box-sizing:border-box;margin:0;padding:0} | |
| body{font-family:'Inter',-apple-system,'Segoe UI',Roboto,sans-serif;background:radial-gradient(1200px 600px at 70% -10%,rgba(99,102,241,.15),transparent),var(--bg);color:var(--text);min-height:100dvh;display:flex;flex-direction:column} | |
| .top{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--border)} | |
| .logo{display:flex;align-items:center;gap:10px;font-weight:700;font-size:1.05rem} | |
| .logo svg{width:22px;height:22px;stroke:var(--primary);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round} | |
| .badge{font-size:.65rem;color:var(--primary);border:1px solid var(--primary);padding:3px 8px;border-radius:99px;letter-spacing:.06em;text-transform:uppercase} | |
| main{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px;gap:18px} | |
| .card{width:min(920px,100%);background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;display:flex;align-items:center;justify-content:center;min-height:220px} | |
| .card img,.card video{width:100%;max-height:70vh;object-fit:contain;background:#000} | |
| .card audio{width:90%;margin:40px 0} | |
| .card iframe{width:100%;height:70vh;border:none} | |
| .card .no{padding:48px;text-align:center;color:var(--muted)} | |
| .card .no svg{width:56px;height:56px;stroke:var(--muted);fill:none;stroke-width:1.5;margin-bottom:12px;stroke-linecap:round;stroke-linejoin:round} | |
| .card .no.err{color:var(--danger);font-weight:600} | |
| .meta{text-align:center;max-width:90%} | |
| .name{font-weight:600;font-size:1.05rem;word-break:break-all} | |
| .sub{color:var(--muted);font-size:.8rem;margin-top:4px} | |
| .btn{display:inline-flex;align-items:center;gap:8px;background:var(--primary);color:#fff;text-decoration:none;padding:12px 22px;border-radius:10px;font-weight:600;font-size:.95rem;transition:filter .15s;border:none;cursor:pointer} | |
| .btn:hover{filter:brightness(1.1)} | |
| .btn svg{width:18px;height:18px;stroke:#fff;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round} | |
| .foot{color:var(--muted);font-size:.7rem;margin-top:6px} | |
| /* Liste dossier */ | |
| .folder-list{width:min(920px,100%);background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden} | |
| .folder-list-head{padding:16px 18px;border-bottom:1px solid var(--border);font-weight:600;display:flex;align-items:center;gap:10px} | |
| .folder-list-head svg{width:20px;height:20px;stroke:var(--primary);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round} | |
| .folder-item{display:flex;align-items:center;gap:14px;padding:13px 18px;border-bottom:1px solid var(--border);transition:background .15s} | |
| .folder-item:last-child{border-bottom:none} | |
| .folder-item:hover{background:rgba(99,102,241,.07)} | |
| .folder-item .fi-icon{width:38px;height:38px;border-radius:8px;background:rgba(99,102,241,.12);display:flex;align-items:center;justify-content:center;flex-shrink:0} | |
| .folder-item .fi-icon svg{width:18px;height:18px;stroke:var(--primary);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round} | |
| .folder-item .fi-info{flex:1;min-width:0} | |
| .folder-item .fi-name{font-weight:500;font-size:.92rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} | |
| .folder-item .fi-size{color:var(--muted);font-size:.75rem;margin-top:2px} | |
| .folder-item .fi-dl{flex-shrink:0} | |
| .folder-empty{padding:48px;text-align:center;color:var(--muted)} | |
| @media (max-width:560px){.folder-item{flex-wrap:wrap}.folder-item .fi-dl{width:100%;justify-content:center;margin-top:6px;display:flex}} | |
| </style> | |
| </head> | |
| <body> | |
| <header class="top"> | |
| <div class="logo"><svg viewBox="0 0 24 24"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg> PixelDrive</div> | |
| <span class="badge">Zero-Knowledge</span> | |
| </header> | |
| <main id="main"></main> | |
| <script> | |
| const D = __EMBED_DATA__; | |
| const main = document.getElementById('main'); | |
| function fmt(b){if(b==null)return'—';if(b<1024)return b+' B';if(b<1048576)return(b/1024).toFixed(0)+' KB';if(b<1073741824)return(b/1048576).toFixed(1)+' MB';return(b/1073741824).toFixed(2)+' GB'} | |
| function el(tag, cls, html){const e=document.createElement(tag);if(cls)e.className=cls;if(html!==undefined)e.innerHTML=html;return e} | |
| const ICON_FILE='<svg viewBox="0 0 24 24"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>'; | |
| const ICON_DL='<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>'; | |
| const ICON_FOLDER='<svg viewBox="0 0 24 24"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>'; | |
| if (D.error) { | |
| const card = el('div','card','<div class="no err">'+D.error+'</div>'); | |
| main.appendChild(card); | |
| } else if (D.type === 'folder') { | |
| document.title = D.name + ' · PixelDrive'; | |
| const list = el('div','folder-list'); | |
| list.appendChild(el('div','folder-list-head', ICON_FOLDER + '<span>'+D.name+'</span><span style="color:var(--muted);font-weight:400;font-size:.8rem;margin-left:auto;">'+D.files.length+' fichier(s)</span>')); | |
| if (!D.files.length) { | |
| list.appendChild(el('div','folder-empty','Dossier vide')); | |
| } else { | |
| D.files.forEach(f=>{ | |
| const row = el('div','folder-item'); | |
| row.appendChild(el('div','fi-icon',ICON_FILE)); | |
| const info = el('div','fi-info'); | |
| info.appendChild(el('div','fi-name',f.name)); | |
| info.appendChild(el('div','fi-size',fmt(f.size)+(f.mime?' · '+f.mime:''))); | |
| row.appendChild(info); | |
| const dl = el('a','btn fi-dl', ICON_DL + '<span>Télécharger</span>'); | |
| dl.href = f.dl; dl.download = f.name; | |
| row.appendChild(dl); | |
| list.appendChild(row); | |
| }); | |
| } | |
| main.appendChild(list); | |
| main.appendChild(el('p','foot','Chiffré AES-256-GCM · Propulsé par PixelDrive')); | |
| } else { | |
| document.title = D.name + ' · PixelDrive'; | |
| const card = el('div','card'); | |
| const m = D.mime || ''; | |
| if (m.startsWith('image/')) card.innerHTML = '<img src="'+D.dl+'" alt="">'; | |
| else if (m.startsWith('video/')) card.innerHTML = '<video controls playsinline src="'+D.dl+'"></video>'; | |
| else if (m.startsWith('audio/')) card.innerHTML = '<audio controls src="'+D.dl+'"></audio>'; | |
| else if (m === 'application/pdf') card.innerHTML = '<iframe src="'+D.dl+'"></iframe>'; | |
| else card.innerHTML = '<div class="no">'+ICON_FILE+'<div>Aperçu non disponible</div></div>'; | |
| main.appendChild(card); | |
| const meta = el('div','meta'); | |
| meta.appendChild(el('div','name',D.name)); | |
| meta.appendChild(el('div','sub',fmt(D.size)+(m?' · '+m:''))); | |
| main.appendChild(meta); | |
| const dl = el('a','btn', ICON_DL + '<span>Télécharger</span>'); | |
| dl.href = D.dl; dl.download = D.name; | |
| main.appendChild(dl); | |
| main.appendChild(el('p','foot','Chiffré AES-256-GCM · Propulsé par PixelDrive')); | |
| } | |
| </script> | |
| </body> | |
| </html> |